- static char *buf=NULL;
- int bufsize = sparse_files?SPARSE_WRITE_SIZE:WRITE_SIZE;
- int total=0;
-
- if (!buf) {
- buf = (char *)malloc(bufsize);
- if (!buf) out_of_memory("read_write");
- }
+ int total = 0;
+ fd_set w_fds, r_fds;
+ int fd_count, count, got_select=0;
+ struct timeval tv;
+
+ while (total < len) {
+ int ret = write(fd,buf+total,len-total);
+
+ if (ret == 0) return total;
+
+ if (ret == -1 && !(errno == EWOULDBLOCK || errno == EAGAIN))
+ return -1;
+
+ if (ret == -1 && got_select) {
+ /* hmmm, we got a write select on the fd and
+ then failed to write. Why doesn't that
+ mean that the fd is dead? It doesn't on
+ some systems it seems (eg. IRIX) */
+ u_sleep(1000);
+ }
+
+ got_select = 0;
+
+
+ if (ret != -1) {
+ total += ret;
+ continue;
+ }
+
+ if (read_buffer_len < MAX_READ_BUFFER && buffer_f_in != -1)
+ read_check(buffer_f_in);
+
+ fd_count = fd+1;
+ FD_ZERO(&w_fds);
+ FD_ZERO(&r_fds);
+ FD_SET(fd,&w_fds);
+ if (buffer_f_in != -1) {
+ FD_SET(buffer_f_in,&r_fds);
+ if (buffer_f_in > fd)
+ fd_count = buffer_f_in+1;
+ }
+
+ tv.tv_sec = BLOCKING_TIMEOUT;
+ tv.tv_usec = 0;
+ count = select(fd_count,buffer_f_in == -1? NULL: &r_fds,
+ &w_fds,NULL,&tv);
+
+ if (count == -1 && errno != EINTR) {
+ if (verbose > 1)
+ rprintf(FERROR,"select error: %s\n", strerror(errno));
+ exit_cleanup(1);
+ }
+
+ if (count == 0) {
+ check_timeout();
+ continue;
+ }
+
+ if (FD_ISSET(fd, &w_fds)) {
+ got_select = 1;
+ }
+ }