version 1.251, 2022/12/16 06:52:48 |
version 1.252, 2023/01/10 23:22:15 |
|
|
do_cmd(char *program, char *host, char *remuser, int port, int subsystem, |
do_cmd(char *program, char *host, char *remuser, int port, int subsystem, |
char *cmd, int *fdin, int *fdout, pid_t *pid) |
char *cmd, int *fdin, int *fdout, pid_t *pid) |
{ |
{ |
int pin[2], pout[2], reserved[2]; |
int sv[2]; |
|
|
if (verbose_mode) |
if (verbose_mode) |
fmprintf(stderr, |
fmprintf(stderr, |
|
|
if (port == -1) |
if (port == -1) |
port = sshport; |
port = sshport; |
|
|
/* |
|
* Reserve two descriptors so that the real pipes won't get |
|
* descriptors 0 and 1 because that will screw up dup2 below. |
|
*/ |
|
if (pipe(reserved) == -1) |
|
fatal("pipe: %s", strerror(errno)); |
|
|
|
/* Create a socket pair for communicating with ssh. */ |
/* Create a socket pair for communicating with ssh. */ |
if (pipe(pin) == -1) |
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) |
fatal("pipe: %s", strerror(errno)); |
fatal("socketpair: %s", strerror(errno)); |
if (pipe(pout) == -1) |
|
fatal("pipe: %s", strerror(errno)); |
|
|
|
/* Free the reserved descriptors. */ |
|
close(reserved[0]); |
|
close(reserved[1]); |
|
|
|
ssh_signal(SIGTSTP, suspchild); |
ssh_signal(SIGTSTP, suspchild); |
ssh_signal(SIGTTIN, suspchild); |
ssh_signal(SIGTTIN, suspchild); |
ssh_signal(SIGTTOU, suspchild); |
ssh_signal(SIGTTOU, suspchild); |
|
|
/* Fork a child to execute the command on the remote host using ssh. */ |
/* Fork a child to execute the command on the remote host using ssh. */ |
*pid = fork(); |
*pid = fork(); |
if (*pid == 0) { |
switch (*pid) { |
|
case -1: |
|
fatal("fork: %s", strerror(errno)); |
|
case 0: |
/* Child. */ |
/* Child. */ |
close(pin[1]); |
if (dup2(sv[0], STDIN_FILENO) == -1 || |
close(pout[0]); |
dup2(sv[0], STDOUT_FILENO) == -1) { |
dup2(pin[0], 0); |
perror("dup2"); |
dup2(pout[1], 1); |
_exit(1); |
close(pin[0]); |
} |
close(pout[1]); |
close(sv[0]); |
|
close(sv[1]); |
replacearg(&args, 0, "%s", program); |
replacearg(&args, 0, "%s", program); |
if (port != -1) { |
if (port != -1) { |
addargs(&args, "-p"); |
addargs(&args, "-p"); |
|
|
|
|
execvp(program, args.list); |
execvp(program, args.list); |
perror(program); |
perror(program); |
exit(1); |
_exit(1); |
} else if (*pid == -1) { |
default: |
fatal("fork: %s", strerror(errno)); |
/* Parent. Close the other side, and return the local side. */ |
|
close(sv[0]); |
|
*fdin = sv[1]; |
|
*fdout = sv[1]; |
|
ssh_signal(SIGTERM, killchild); |
|
ssh_signal(SIGINT, killchild); |
|
ssh_signal(SIGHUP, killchild); |
|
return 0; |
} |
} |
/* Parent. Close the other side, and return the local side. */ |
|
close(pin[0]); |
|
*fdout = pin[1]; |
|
close(pout[1]); |
|
*fdin = pout[0]; |
|
ssh_signal(SIGTERM, killchild); |
|
ssh_signal(SIGINT, killchild); |
|
ssh_signal(SIGHUP, killchild); |
|
return 0; |
|
} |
} |
|
|
/* |
/* |