X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/9b3318b0df79ce6e9490c744ef7ae0707bd91599..9eeb3b9c88d62bac0fed650fdbc310d5958cc541:/main.c diff --git a/main.c b/main.c index e0a90455..0c355362 100644 --- a/main.c +++ b/main.c @@ -53,6 +53,7 @@ extern int whole_file; extern int read_batch; extern int write_batch; extern int batch_fd; +extern int batch_gen_fd; extern int filesfrom_fd; extern pid_t cleanup_child_pid; extern char *files_from; @@ -150,6 +151,8 @@ static void report(int f) /* this is the client */ if (!am_sender) { + /* Read the first two in opposite order because the meaning of + * read/write swaps when switching from sender to receiver. */ total_written = read_longint(f); total_read = read_longint(f); stats.total_size = read_longint(f); @@ -311,15 +314,24 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char *path, rprintf(FINFO,"\n"); } - if (local_server) { + if (read_batch) { + int from_gen_pipe[2]; + if (fd_pair(from_gen_pipe) < 0) { + rsyserr(FERROR, errno, "pipe"); + exit_cleanup(RERR_IPC); + } + batch_gen_fd = from_gen_pipe[0]; + *f_out = from_gen_pipe[1]; + *f_in = batch_fd; + ret = -1; /* no child pid */ + } else if (local_server) { /* If the user didn't request --[no-]whole-file, force * it on, but only if we're not batch processing. */ - if (whole_file < 0 && !read_batch && !write_batch) + if (whole_file < 0 && !write_batch) whole_file = 1; ret = local_child(argc, args, f_in, f_out, child_main); - } else { + } else ret = piped_child(args,f_in,f_out); - } if (dir) free(dir); @@ -392,7 +404,7 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[]) (long)getpid()); } - if (am_daemon && lp_write_only(module_id) && am_sender) { + if (am_daemon && lp_write_only(module_id)) { rprintf(FERROR, "ERROR: module is write only\n"); exit_cleanup(RERR_SYNTAX); return; @@ -425,8 +437,9 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[]) exit_cleanup(0); } - io_start_buffering_in(f_in); - io_start_buffering_out(f_out); + io_start_buffering_in(); + io_start_buffering_out(); + send_files(flist,f_out,f_in); io_flush(FULL_FLUSH); report(f_out); @@ -450,9 +463,8 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) if (!delete_after) { /* I moved this here from recv_files() to prevent a race condition */ - if (recurse && delete_mode && !local_name && flist->count>0) { + if (recurse && delete_mode && !local_name && flist->count > 0) delete_files(flist); - } } if (fd_pair(error_pipe) < 0) { @@ -468,7 +480,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) close(f_out); /* we can't let two processes write to the socket at one time */ - io_multiplexing_close(); + close_multiplexing_out(); /* set place to send errors */ set_msg_fd_out(error_pipe[1]); @@ -487,6 +499,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) } am_generator = 1; + close_multiplexing_in(); if (write_batch) stop_write_batch(); @@ -494,7 +507,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) if (f_in != f_out) close(f_in); - io_start_buffering_out(f_out); + io_start_buffering_out(); set_msg_fd_in(error_pipe[0]); @@ -528,7 +541,7 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[]) argc, (long)getpid()); } - if (am_daemon && lp_read_only(module_id) && !am_sender) { + if (am_daemon && lp_read_only(module_id)) { rprintf(FERROR,"ERROR: module is read only\n"); exit_cleanup(RERR_SYNTAX); return; @@ -546,7 +559,7 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[]) } } - io_start_buffering_in(f_in); + io_start_buffering_in(); if (delete_mode && !delete_excluded) recv_exclude_list(f_in); @@ -588,13 +601,14 @@ int child_main(int argc, char *argv[]) void start_server(int f_in, int f_out, int argc, char *argv[]) { - setup_protocol(f_out, f_in); - set_nonblocking(f_in); set_nonblocking(f_out); + io_set_sock_fds(f_in, f_out); + setup_protocol(f_out, f_in); + if (protocol_version >= 23) - io_start_multiplex_out(f_out); + io_start_multiplex_out(); if (am_sender) { keep_dirlinks = 0; /* Must be disabled on the sender. */ @@ -622,27 +636,21 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) cleanup_child_pid = pid; if (read_batch) { - /* This is the heart of the read_batch approach: - * Switcher-roo the file descriptors, and - * nobody's the wiser. */ - close(f_in); - close(f_out); - f_in = batch_fd; - f_out = do_open("/dev/null", O_WRONLY, 0); assert(am_sender == 0); } else { set_nonblocking(f_in); set_nonblocking(f_out); } + io_set_sock_fds(f_in, f_out); setup_protocol(f_out,f_in); if (protocol_version >= 23 && !read_batch) - io_start_multiplex_in(f_in); + io_start_multiplex_in(); if (am_sender) { keep_dirlinks = 0; /* Must be disabled on the sender. */ - io_start_buffering_out(f_out); + io_start_buffering_out(); if (cvs_exclude) add_cvs_excludes(); if (delete_mode && !delete_excluded) @@ -652,8 +660,6 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) if (write_batch) start_write_batch(f_out); - /* Can be unconditional, but this is theoretically - * more efficent for read_batch case. */ if (!read_batch) /* don't write to pipe */ flist = send_file_list(f_out,argc,argv); if (verbose > 3) @@ -680,8 +686,6 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) if (argc == 0) list_only = 1; - /* Can be unconditional, but this is theoretically more - * efficient for the read_batch case. */ if (!read_batch) send_exclude_list(f_out); @@ -1017,11 +1021,8 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig)) int main(int argc,char *argv[]) { int ret; - int orig_argc; - char **orig_argv; - - orig_argc = argc; - orig_argv = argv; + int orig_argc = argc; + char **orig_argv = argv; signal(SIGUSR1, sigusr1_handler); signal(SIGUSR2, sigusr2_handler); @@ -1072,16 +1073,22 @@ int main(int argc,char *argv[]) if (write_batch || read_batch) { if (write_batch) - write_batch_argvs_file(orig_argc, orig_argv); + write_batch_shell_file(orig_argc, orig_argv, argc); - batch_fd = do_open(batch_name, + if (read_batch && strcmp(batch_name, "-") == 0) + batch_fd = STDIN_FILENO; + else { + batch_fd = do_open(batch_name, write_batch ? O_WRONLY | O_CREAT | O_TRUNC : O_RDONLY, S_IRUSR | S_IWUSR); + } if (batch_fd < 0) { rsyserr(FERROR, errno, "Batch file %s open error", batch_name); exit_cleanup(RERR_FILEIO); } + if (read_batch) + read_stream_flags(batch_fd); } if (am_daemon && !am_server)