[Bug 369] Inconsistant exiit status from scp
Thomas Binder
binder at arago.de
Wed Sep 11 03:36:45 EST 2002
Hi!
> ------- Additional Comments From markus at openbsd.org 2002-09-10 22:45 -------
> do you have a patch for checking the exit status of ssh?
I attached a rough patch for that. It probably (I haven't been
able to check) has one drawback, though: If the remote sshd has
the "scp hangs on exit" problem, then the patched local scp will
now do so, too.
Besides, the patch also adds a check for fork() returning an
error.
Ciao
Thomas
-------------- next part --------------
? confdefs.h
Index: scp.c
===================================================================
RCS file: /cvs/openssh/scp.c,v
retrieving revision 1.97
diff -u -r1.97 scp.c
--- scp.c 21 Jun 2002 00:41:52 -0000 1.97
+++ scp.c 10 Sep 2002 17:16:29 -0000
@@ -125,6 +125,9 @@
/* This is the program to execute for the secured connection. ("ssh" or -S) */
char *ssh_program = _PATH_SSH_PROGRAM;
+/* This is used to store the pid of ssh_program */
+pid_t do_cmd_pid;
+
/*
* This function executes the given command as the specified user on the
* given host. This returns < 0 if execution fails, and >= 0 otherwise. This
@@ -159,7 +162,8 @@
close(reserved[1]);
/* For a child to execute the command on the remote host using ssh. */
- if (fork() == 0) {
+ do_cmd_pid = fork();
+ if (do_cmd_pid == 0) {
/* Child. */
close(pin[1]);
close(pout[0]);
@@ -178,6 +182,10 @@
perror(ssh_program);
exit(1);
}
+ else if (do_cmd_pid == (pid_t)-1) {
+ /* fork() failed */
+ fatal("fork: %s", strerror(errno));
+ }
/* Parent. Close the other side, and return the local side. */
close(pin[0]);
*fdout = pin[1];
@@ -219,7 +227,7 @@
int argc;
char *argv[];
{
- int ch, fflag, tflag;
+ int ch, fflag, tflag, status;
char *targ;
extern char *optarg;
extern int optind;
@@ -317,6 +325,7 @@
targetshouldbedirectory = 1;
remin = remout = -1;
+ do_cmd_pid = (pid_t)-1;
/* Command to be executed on remote system using "ssh". */
(void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s",
verbose_mode ? " -v" : "",
@@ -331,6 +340,22 @@
tolocal(argc, argv); /* Dest is local host. */
if (targetshouldbedirectory)
verifydir(argv[argc - 1]);
+ }
+ /*
+ * Finally check the exit status of the ssh process, if one was forked
+ * and no error has occured yet
+ */
+ if (do_cmd_pid != (pid_t)-1 && errs == 0) {
+ if (remin != -1)
+ (void) close(remin);
+ if (remout != -1)
+ (void) close(remout);
+ if (waitpid(do_cmd_pid, &status, 0) == -1)
+ errs = 1;
+ else {
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ errs = 1;
+ }
}
exit(errs != 0);
}
More information about the openssh-unix-dev
mailing list