X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/d79d1c69f77dd6cc23a4692f6b8bdd82e181194e..14175f1e7700e4e800692fc2c466cbd27a60176e:/util.c diff --git a/util.c b/util.c index 3cb80eb9..7c589b37 100644 --- a/util.c +++ b/util.c @@ -26,15 +26,71 @@ extern int verbose; -/* this is taken from CVS */ + +/**************************************************************************** +Set a fd into nonblocking mode +****************************************************************************/ +void set_nonblocking(int fd) +{ + int val; + + if((val = fcntl(fd, F_GETFL, 0)) == -1) + return; + if (!(val & NONBLOCK_FLAG)) { + val |= NONBLOCK_FLAG; + fcntl(fd, F_SETFL, val); + } +} + +/**************************************************************************** +Set a fd into blocking mode +****************************************************************************/ +void set_blocking(int fd) +{ + int val; + + if((val = fcntl(fd, F_GETFL, 0)) == -1) + return; + if (val & NONBLOCK_FLAG) { + val &= ~NONBLOCK_FLAG; + fcntl(fd, F_SETFL, val); + } +} + + +/* create a file descriptor pair - like pipe() but use socketpair if + possible (because of blocking issues on pipes) + + always set non-blocking + */ +int fd_pair(int fd[2]) +{ + int ret; + +#if HAVE_SOCKETPAIR + ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd); +#else + ret = pipe(fd); +#endif + + if (ret == 0) { + set_nonblocking(fd[0]); + set_nonblocking(fd[1]); + } + + return ret; +} + + +/* this is derived from CVS code */ int piped_child(char **command,int *f_in,int *f_out) { int pid; int to_child_pipe[2]; int from_child_pipe[2]; - if (pipe(to_child_pipe) < 0 || - pipe(from_child_pipe) < 0) { + if (fd_pair(to_child_pipe) < 0 || + fd_pair(from_child_pipe) < 0) { rprintf(FERROR,"pipe: %s\n",strerror(errno)); exit_cleanup(RERR_IPC); } @@ -59,6 +115,7 @@ int piped_child(char **command,int *f_in,int *f_out) if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]); if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]); umask(orig_umask); + set_blocking(STDIN_FILENO); execvp(command[0], command); rprintf(FERROR,"Failed to exec %s : %s\n", command[0],strerror(errno)); @@ -83,8 +140,8 @@ int local_child(int argc, char **argv,int *f_in,int *f_out) int to_child_pipe[2]; int from_child_pipe[2]; - if (pipe(to_child_pipe) < 0 || - pipe(from_child_pipe) < 0) { + if (fd_pair(to_child_pipe) < 0 || + fd_pair(from_child_pipe) < 0) { rprintf(FERROR,"pipe: %s\n",strerror(errno)); exit_cleanup(RERR_IPC); } @@ -367,17 +424,6 @@ int robust_rename(char *from, char *to) return -1; return do_rename(from, to); #endif - } - - -/* 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); } @@ -778,12 +824,12 @@ int u_strcmp(const char *cs1, const char *cs2) static OFF_T last_ofs; -void end_progress(void) +void end_progress(OFF_T size) { extern int do_progress, am_server; if (do_progress && !am_server) { - rprintf(FINFO,"\n"); + rprintf(FINFO,"%.0f (100%%)\n", (double)size); } last_ofs = 0; } @@ -874,6 +920,9 @@ char *timestring(time_t t) /**************************************************************************** like waitpid but does the WEXITSTATUS ****************************************************************************/ +#ifndef WEXITSTATUS +#define WEXITSTATUS(stat) ((int)(((stat)>>8)&0xFF)) +#endif void wait_process(pid_t pid, int *status) { waitpid(pid, status, 0);