X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/b67381d0dcd437cb60cef565264b69137918c69f..088aac85971f3f1571c7f90569c95d5025b1fd82:/main.c diff --git a/main.c b/main.c index 50005aac..0ed7df38 100644 --- a/main.c +++ b/main.c @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 by Andrew Tridgell Copyright (C) Paul Mackerras 1996 + Copyright (C) 2001, 2002 by Martin Pool This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +27,7 @@ struct stats stats; extern int verbose; +static void show_malloc_stats(void); /**************************************************************************** wait for a process to exit, calling io_flush while waiting @@ -55,6 +57,12 @@ static void report(int f) extern int remote_version; int send_stats; + if (do_stats) { + /* These come out from every process */ + show_malloc_stats(); + show_flist_stats(); + } + if (am_daemon) { log_exit(0, __FILE__, __LINE__); if (f == -1 || !am_sender) return; @@ -125,6 +133,38 @@ static void report(int f) } +/** + * If our C library can get malloc statistics, then show them to FINFO + **/ +static void show_malloc_stats(void) +{ +#ifdef HAVE_MALLINFO + struct mallinfo mi; + extern int am_server; + extern int am_sender; + extern int am_daemon; + + mi = mallinfo(); + + rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n", + getpid(), + am_server ? "server " : "", + am_daemon ? "daemon " : "", + am_sender ? "sender" : "receiver"); + rprintf(FINFO, " arena: %10d (bytes from sbrk)\n", mi.arena); + rprintf(FINFO, " ordblks: %10d (chunks not in use)\n", mi.ordblks); + rprintf(FINFO, " smblks: %10d\n", mi.smblks); + rprintf(FINFO, " hblks: %10d (chunks from mmap)\n", mi.hblks); + rprintf(FINFO, " hblkhd: %10d (bytes from mmap)\n", mi.hblkhd); + rprintf(FINFO, " usmblks: %10d\n", mi.usmblks); + rprintf(FINFO, " fsmblks: %10d\n", mi.fsmblks); + rprintf(FINFO, " uordblks: %10d (bytes used)\n", mi.uordblks); + rprintf(FINFO, " fordblks: %10d (bytes free)\n", mi.fordblks); + rprintf(FINFO, " keepcost: %10d (bytes in releasable chunk)\n", mi.keepcost); +#endif /* HAVE_MALLINFO */ +} + + /* Start the remote shell. cmd may be NULL to use the default. */ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out) { @@ -137,7 +177,7 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int extern int blocking_io; extern int read_batch; - if (!read_batch && !local_server) { /* dw -- added read_batch */ + if (!read_batch && !local_server) { if (!cmd) cmd = getenv(RSYNC_RSH_ENV); if (!cmd) @@ -167,10 +207,11 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int args[argc++] = rsync_path; - server_options(args,&argc); + if ((blocking_io == -1) && (strcmp(cmd, RSYNC_RSH) == 0)) + blocking_io = 1; + server_options(args,&argc); - if (strcmp(cmd, RSYNC_RSH) == 0) blocking_io = 1; } args[argc++] = "."; @@ -189,7 +230,7 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int if (local_server) { if (read_batch) - create_flist_from_batch(); + create_flist_from_batch(); /* sets batch_flist */ ret = local_child(argc, args, f_in, f_out); } else { ret = piped_child(args,f_in,f_out); @@ -402,8 +443,8 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[]) extern int am_daemon; extern int module_id; extern int am_sender; - extern int read_batch; /* dw */ - extern struct file_list *batch_flist; /* dw */ + extern int read_batch; + extern struct file_list *batch_flist; if (verbose > 2) rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid()); @@ -429,7 +470,7 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[]) if (delete_mode && !delete_excluded) recv_exclude_list(f_in); - if (read_batch) /* dw */ + if (read_batch) flist = batch_flist; else flist = recv_file_list(f_in); @@ -456,7 +497,7 @@ void start_server(int f_in, int f_out, int argc, char *argv[]) extern int cvs_exclude; extern int am_sender; extern int remote_version; - extern int read_batch; /* dw */ + extern int read_batch; setup_protocol(f_out, f_in); @@ -467,7 +508,7 @@ void start_server(int f_in, int f_out, int argc, char *argv[]) io_start_multiplex_out(f_out); if (am_sender) { - if (!read_batch) { /* dw */ + if (!read_batch) { recv_exclude_list(f_in); if (cvs_exclude) add_cvs_excludes(); @@ -486,19 +527,19 @@ void start_server(int f_in, int f_out, int argc, char *argv[]) */ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) { - struct file_list *flist; + struct file_list *flist = NULL; int status = 0, status2 = 0; char *local_name = NULL; extern int am_sender; extern int remote_version; extern pid_t cleanup_child_pid; - extern int write_batch; /* dw */ - extern int read_batch; /* dw */ - extern struct file_list *batch_flist; /* dw */ + extern int write_batch; + extern int read_batch; + extern struct file_list *batch_flist; cleanup_child_pid = pid; if (read_batch) - flist = batch_flist; /* dw */ + flist = batch_flist; set_nonblocking(f_in); set_nonblocking(f_out); @@ -528,7 +569,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) } if (pid != -1) { if (verbose > 3) - rprintf(FINFO,"client_run waiting on %d\n",pid); + rprintf(FINFO,"client_run waiting on %d\n", (int) pid); io_flush(); wait_process(pid, &status); } @@ -541,7 +582,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) list_only = 1; } - if (!write_batch) /* dw */ + if (!write_batch) send_exclude_list(f_out); flist = recv_file_list(f_in); @@ -558,7 +599,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) if (pid != -1) { if (verbose > 3) - rprintf(FINFO,"client_run2 waiting on %d\n",pid); + rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid); io_flush(); wait_process(pid, &status); } @@ -582,6 +623,22 @@ static char *find_colon(char *s) } +static int copy_argv (char *argv[]) +{ + int i; + + for (i = 0; argv[i]; i++) { + if (!(argv[i] = strdup(argv[i]))) { + rprintf (FERROR, "out of memory at %s(%d)\n", + __FILE__, __LINE__); + return RERR_MALLOC; + } + } + + return 0; +} + + /* * Start a client for either type of remote connection. Work out * whether the arguments request a remote shell or rsyncd connection, @@ -601,13 +658,19 @@ static int start_client(int argc, char *argv[]) extern char *shell_cmd; extern int rsync_port; extern int whole_file; - char *argv0 = strdup(argv[0]); + extern int write_batch; extern int read_batch; + int rc; + + /* Don't clobber argv[] so that ps(1) can still show the right + command line. */ + if ((rc = copy_argv (argv))) + return rc; - if (strncasecmp(URL_PREFIX, argv0, strlen(URL_PREFIX)) == 0) { + if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0) { char *host, *path; - host = argv0 + strlen(URL_PREFIX); + host = argv[0] + strlen(URL_PREFIX); p = strchr(host,'/'); if (p) { *p = 0; @@ -623,13 +686,13 @@ static int start_client(int argc, char *argv[]) return start_socket_client(host, path, argc-1, argv+1); } - if (!read_batch) { /* dw */ + if (!read_batch) { p = find_colon(argv[0]); if (p) { if (p[1] == ':') { *p = 0; - return start_socket_client(argv0, p+2, argc-1, argv+1); + return start_socket_client(argv[0], p+2, argc-1, argv+1); } if (argc < 1) { @@ -639,7 +702,7 @@ static int start_client(int argc, char *argv[]) am_sender = 0; *p = 0; - shell_machine = argv0; + shell_machine = argv[0]; shell_path = p+1; argc--; argv++; @@ -649,8 +712,12 @@ static int start_client(int argc, char *argv[]) p = find_colon(argv[argc-1]); if (!p) { local_server = 1; - /* disable "rsync algorithm" when both sides local */ - whole_file = 1; + /* + * disable "rsync algorithm" when both sides local, + * except when creating a batch update + */ + if (!write_batch && whole_file == -1) + whole_file = 1; } else if (p[1] == ':') { *p = 0; return start_socket_client(argv[argc-1], p+2, argc-1, argv); @@ -672,9 +739,9 @@ static int start_client(int argc, char *argv[]) argc--; } } else { - am_sender = 1; /* dw */ - local_server = 1; /* dw */ - shell_path = argv[argc-1]; /* dw */ + am_sender = 1; + local_server = 1; + shell_path = argv[argc-1]; } if (shell_machine) { @@ -739,12 +806,12 @@ int main(int argc,char *argv[]) extern int am_daemon; extern int am_server; int ret; - extern int read_batch; /* dw */ - extern int write_batch; /* dw */ - extern char *batch_ext; /* dw */ - int orig_argc; /* dw */ + extern int write_batch; + int orig_argc; + char **orig_argv; - orig_argc = argc; /* dw */ + orig_argc = argc; + orig_argv = argv; signal(SIGUSR1, sigusr1_handler); signal(SIGUSR2, sigusr2_handler); @@ -782,13 +849,8 @@ int main(int argc,char *argv[]) that implement getcwd that way "pwd" can't be found after chroot. */ push_dir(NULL,0); - if (write_batch) { /* dw */ - create_batch_file_ext(); - write_batch_argvs_file(orig_argc, argc, argv); - } - - if (read_batch) { /* dw */ - set_batch_file_ext(batch_ext); + if (write_batch && !am_server) { + write_batch_argvs_file(orig_argc, orig_argv); } if (am_daemon) { @@ -817,7 +879,9 @@ int main(int argc,char *argv[]) } ret = start_client(argc, argv); - exit_cleanup(ret); + if (ret == -1) + exit_cleanup(RERR_STARTCLIENT); + else + exit_cleanup(ret); return ret; } -