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);
}
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));
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);
}
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);
}
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;
}