X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/6574b4f7d938a90a158ba31c03942f8170452df4..a76a0039fc6f02f88dd1aba866c03ceefa7fafec:/util.c diff --git a/util.c b/util.c index e53d02a0..6537717d 100644 --- a/util.c +++ b/util.c @@ -82,9 +82,9 @@ char *map_ptr(struct map_struct *map,off_t offset,int len) if (lseek(map->fd,offset,SEEK_SET) != offset || (nread=read(map->fd,map->p,len)) != len) { - fprintf(FERROR,"EOF in map_ptr! (offset=%d len=%d nread=%d errno=%d)\n", - (int)offset, len, nread, errno); - exit_cleanup(1); + fprintf(FERROR,"EOF in map_ptr! (offset=%d len=%d nread=%d errno=%d)\n", + (int)offset, len, nread, errno); + exit_cleanup(1); } map->p_offset = offset; @@ -119,7 +119,7 @@ int piped_child(char **command,int *f_in,int *f_out) } - pid = fork(); + pid = do_fork(); if (pid < 0) { fprintf(FERROR,"fork: %s\n",strerror(errno)); exit_cleanup(1); @@ -164,21 +164,10 @@ void out_of_memory(char *str) } -#ifndef HAVE_STRDUP - char *strdup(char *s) -{ - int l = strlen(s) + 1; - char *ret = (char *)malloc(l); - if (ret) - strcpy(ret,s); - return ret; -} -#endif - int set_modtime(char *fname,time_t modtime) { -#ifdef HAVE_UTIME_H +#ifdef HAVE_UTIMBUF struct utimbuf tbuf; tbuf.actime = time(NULL); tbuf.modtime = modtime; @@ -251,3 +240,140 @@ int create_directory_path(char *fname) } return 0; } + + +/* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted. + Return LEN upon success, write's (negative) error code otherwise. + + derived from GNU C's cccp.c. +*/ +int full_write(int desc, char *ptr, int len) +{ + int total_written; + + total_written = 0; + while (len > 0) { + int written = write (desc, ptr, len); + if (written < 0) { +#ifdef EINTR + if (errno == EINTR) + continue; +#endif + return written; + } + total_written += written; + ptr += written; + len -= written; + } + return total_written; +} + +/* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted. + Return the actual number of bytes read, zero for EOF, or negative + for an error. + + derived from GNU C's cccp.c. */ +int safe_read(int desc, char *ptr, int len) +{ + int n_chars; + + if (len <= 0) + return len; + +#ifdef EINTR + do { + n_chars = read(desc, ptr, len); + } while (n_chars < 0 && errno == EINTR); +#else + n_chars = read(desc, ptr, len); +#endif + + return n_chars; +} + + +/* copy a file - this is used in conjunction with the --temp-dir option */ +int copy_file(char *source, char *dest, mode_t mode) +{ + int ifd; + int ofd; + char buf[1024 * 8]; + int len; /* Number of bytes read into `buf'. */ + + ifd = open(source, O_RDONLY); + if (ifd == -1) { + fprintf(FERROR,"open %s: %s\n", + source,strerror(errno)); + return -1; + } + + if (unlink(dest) && errno != ENOENT) { + fprintf(FERROR,"unlink %s: %s\n", + dest,strerror(errno)); + return -1; + } + + ofd = open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode); + if (ofd < 0) { + fprintf(FERROR,"open %s: %s\n", + dest,strerror(errno)); + close(ifd); + return -1; + } + + while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) { + if (full_write(ofd, buf, len) < 0) { + fprintf(FERROR,"write %s: %s\n", + dest,strerror(errno)); + close(ifd); + close(ofd); + return -1; + } + } + + close(ifd); + close(ofd); + + if (len < 0) { + fprintf(FERROR,"read %s: %s\n", + source,strerror(errno)); + return -1; + } + + return 0; +} + +/* sleep for a while via select */ +void u_sleep(int usec) +{ + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = usec; + select(0, NULL, NULL, NULL, &tv); +} + + +static pid_t all_pids[10]; +static int num_pids; + +/* fork and record the pid of the child */ +pid_t do_fork(void) +{ + pid_t newpid = fork(); + + if (newpid) { + all_pids[num_pids++] = newpid; + } + return newpid; +} + +/* kill all children */ +void kill_all(int sig) +{ + int i; + for (i=0;i