Commit 19b27a48 authored by Andrew Tridgell's avatar Andrew Tridgell

improved error handling again. Now we report messages for the remote

shell failing and propogate errors in a better fashion
parent ff81e809
......@@ -33,6 +33,7 @@ static struct map_struct *cleanup_buf;
static int cleanup_pid = 0;
extern int io_error;
pid_t cleanup_child_pid = -1;
/*
* Code is one of the RERR_* codes from errcode.h.
......@@ -42,11 +43,17 @@ void _exit_cleanup(int code, const char *file, int line)
extern int keep_partial;
extern int log_got_error;
if (code == 0 && io_error) code = RERR_FILEIO;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
if (cleanup_child_pid != -1) {
int status;
if (waitpid(cleanup_child_pid, &status, WNOHANG) == cleanup_child_pid) {
status = WEXITSTATUS(status);
if (status > code) code = status;
}
}
if (cleanup_got_literal && cleanup_fname && keep_partial) {
char *fname = cleanup_fname;
cleanup_fname = NULL;
......@@ -68,14 +75,12 @@ void _exit_cleanup(int code, const char *file, int line)
}
}
if (code) log_exit(code, file, line);
if (code == 0) {
if (log_got_error) {
code = RERR_FILEIO;
}
if (code == 0 && (io_error || log_got_error)) {
code = RERR_PARTIAL;
}
if (code) log_exit(code, file, line);
exit(code);
}
......
......@@ -36,5 +36,22 @@
#define RERR_SIGNAL 20 /* status returned when sent SIGUSR1, SIGINT */
#define RERR_WAITCHILD 21 /* some error returned by waitpid() */
#define RERR_MALLOC 22 /* error allocating core memory buffers */
#define RERR_PARTIAL 23 /* partial transfer */
#define RERR_TIMEOUT 30 /* timeout in data send/receive */
/* Although it doesn't seem to be specified anywhere,
* ssh and the shell seem to return these values:
*
* 124 if the command exited with status 255
* 125 if the command is killed by a signal
* 126 if the command cannot be run
* 127 if the command is not found
*
* and we could use this to give a better explanation if the remote
* command is not found.
*/
#define RERR_CMD_FAILED 124
#define RERR_CMD_KILLED 125
#define RERR_CMD_RUN 126
#define RERR_CMD_NOTFOUND 127
......@@ -40,7 +40,7 @@ struct {
{ RERR_SYNTAX , "syntax or usage error" },
{ RERR_PROTOCOL , "protocol incompatibility" },
{ RERR_FILESELECT , "errors selecting input/output files, dirs" },
{ RERR_UNSUPPORTED , "requested action not supported" },
{ RERR_UNSUPPORTED, "requested action not supported" },
{ RERR_SOCKETIO , "error in socket IO" },
{ RERR_FILEIO , "error in file IO" },
{ RERR_STREAMIO , "error in rsync protocol data stream" },
......@@ -49,7 +49,12 @@ struct {
{ RERR_SIGNAL , "received SIGUSR1 or SIGINT" },
{ RERR_WAITCHILD , "some error returned by waitpid()" },
{ RERR_MALLOC , "error allocating core memory buffers" },
{ RERR_PARTIAL , "partial transfer" },
{ RERR_TIMEOUT , "timeout in data send/receive" },
{ RERR_CMD_FAILED , "remote shell failed" },
{ RERR_CMD_KILLED , "remote shell killed" },
{ RERR_CMD_RUN, "remote command could not be run" },
{ RERR_CMD_NOTFOUND, "remote command not found" },
{ 0, NULL }
};
......@@ -506,7 +511,7 @@ void log_exit(int code, const char *file, int line)
if (!name)
name = "unexplained error";
rprintf(FLOG,"transfer interrupted: %s (code %d) at %s(%d)\n",
rprintf(FERROR,"transfer error: %s (code %d) at %s(%d)\n",
name, code, file, line);
}
}
......
......@@ -126,23 +126,11 @@ static void report(int f)
/* Start the remote shell. cmd may be NULL to use the default. */
/* TODO: When the shell exits, look at its return value, as this may
* well tell us if something went wrong in trying to connect to the
* remote machine. Although it doesn't seem to be specified anywhere,
* ssh and the shell seem to return these values:
*
* 124 if the command exited with status 255
* 125 if the command is killed by a signal
* 126 if the command cannot be run
* 127 if the command is not found
*
* and we could use this to give a better explanation if the remote
* command is not found.
*/
static int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
{
char *args[100];
int i,argc=0, ret;
int i,argc=0;
pid_t ret;
char *tok,*dir=NULL;
extern int local_server;
extern char *rsync_path;
......@@ -484,13 +472,16 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
* This is called once the connection has been negotiated. It is used
* for rsyncd, remote-shell, and local connections.
*/
int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
{
struct file_list *flist;
int status = 0, status2 = 0;
char *local_name = NULL;
extern int am_sender;
extern int remote_version;
extern pid_t cleanup_child_pid;
cleanup_child_pid = pid;
set_nonblocking(f_in);
set_nonblocking(f_out);
......@@ -583,7 +574,8 @@ static int start_client(int argc, char *argv[])
char *shell_machine = NULL;
char *shell_path = NULL;
char *shell_user = NULL;
int pid, ret;
int ret;
pid_t pid;
int f_in,f_out;
extern int local_server;
extern int am_sender;
......@@ -700,10 +692,13 @@ static RETSIGTYPE sigusr1_handler(int val) {
static RETSIGTYPE sigusr2_handler(int val) {
extern int log_got_error;
if (log_got_error) _exit(RERR_FILEIO);
if (log_got_error) _exit(RERR_PARTIAL);
_exit(0);
}
static RETSIGTYPE sigchld_handler(int val) {
}
int main(int argc,char *argv[])
{
extern int am_root;
......@@ -715,6 +710,7 @@ int main(int argc,char *argv[])
signal(SIGUSR1, sigusr1_handler);
signal(SIGUSR2, sigusr2_handler);
signal(SIGCHLD, sigchld_handler);
starttime = time(NULL);
am_root = (getuid() == 0);
......
......@@ -93,9 +93,9 @@ int fd_pair(int fd[2])
used to cope with badly broken rsh implementations like the one on
solaris.
*/
int piped_child(char **command,int *f_in,int *f_out)
pid_t piped_child(char **command,int *f_in,int *f_out)
{
int pid;
pid_t pid;
int to_child_pipe[2];
int from_child_pipe[2];
extern int blocking_io;
......@@ -108,7 +108,7 @@ int piped_child(char **command,int *f_in,int *f_out)
pid = do_fork();
if (pid < 0) {
if (pid == -1) {
rprintf(FERROR,"fork: %s\n",strerror(errno));
exit_cleanup(RERR_IPC);
}
......@@ -148,9 +148,9 @@ int piped_child(char **command,int *f_in,int *f_out)
return pid;
}
int local_child(int argc, char **argv,int *f_in,int *f_out)
pid_t local_child(int argc, char **argv,int *f_in,int *f_out)
{
int pid;
pid_t pid;
int to_child_pipe[2];
int from_child_pipe[2];
......@@ -162,7 +162,7 @@ int local_child(int argc, char **argv,int *f_in,int *f_out)
pid = do_fork();
if (pid < 0) {
if (pid == -1) {
rprintf(FERROR,"fork: %s\n",strerror(errno));
exit_cleanup(RERR_IPC);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment