version 1.237, 2008/05/08 12:21:16 |
version 1.238, 2008/05/09 16:16:06 |
|
|
} |
} |
} |
} |
|
|
|
#define USE_PIPES |
/* |
/* |
* This is called to fork and execute a command when we have no tty. This |
* This is called to fork and execute a command when we have no tty. This |
* will call do_child from the child, and server_loop from the parent after |
* will call do_child from the child, and server_loop from the parent after |
|
|
do_exec_no_pty(Session *s, const char *command) |
do_exec_no_pty(Session *s, const char *command) |
{ |
{ |
pid_t pid; |
pid_t pid; |
|
#ifdef USE_PIPES |
|
int pin[2], pout[2], perr[2]; |
|
|
|
/* Allocate pipes for communicating with the program. */ |
|
if (pipe(pin) < 0) { |
|
error("%s: pipe in: %.100s", __func__, strerror(errno)); |
|
return -1; |
|
} |
|
if (pipe(pout) < 0) { |
|
error("%s: pipe out: %.100s", __func__, strerror(errno)); |
|
close(pin[0]); |
|
close(pin[1]); |
|
return -1; |
|
} |
|
if (pipe(perr) < 0) { |
|
error("%s: pipe err: %.100s", __func__, strerror(errno)); |
|
close(pin[0]); |
|
close(pin[1]); |
|
close(pout[0]); |
|
close(pout[1]); |
|
return -1; |
|
} |
|
#else |
int inout[2], err[2]; |
int inout[2], err[2]; |
|
|
/* Uses socket pairs to communicate with the program. */ |
/* Uses socket pairs to communicate with the program. */ |
|
|
close(inout[1]); |
close(inout[1]); |
return -1; |
return -1; |
} |
} |
|
#endif |
|
|
if (s == NULL) |
if (s == NULL) |
fatal("do_exec_no_pty: no session"); |
fatal("do_exec_no_pty: no session"); |
|
|
switch ((pid = fork())) { |
switch ((pid = fork())) { |
case -1: |
case -1: |
error("%s: fork: %.100s", __func__, strerror(errno)); |
error("%s: fork: %.100s", __func__, strerror(errno)); |
|
#ifdef USE_PIPES |
|
close(pin[0]); |
|
close(pin[1]); |
|
close(pout[0]); |
|
close(pout[1]); |
|
close(perr[0]); |
|
close(perr[1]); |
|
#else |
close(inout[0]); |
close(inout[0]); |
close(inout[1]); |
close(inout[1]); |
close(err[0]); |
close(err[0]); |
close(err[1]); |
close(err[1]); |
|
#endif |
return -1; |
return -1; |
case 0: |
case 0: |
is_child = 1; |
is_child = 1; |
|
|
if (setsid() < 0) |
if (setsid() < 0) |
error("setsid failed: %.100s", strerror(errno)); |
error("setsid failed: %.100s", strerror(errno)); |
|
|
|
#ifdef USE_PIPES |
/* |
/* |
|
* Redirect stdin. We close the parent side of the socket |
|
* pair, and make the child side the standard input. |
|
*/ |
|
close(pin[1]); |
|
if (dup2(pin[0], 0) < 0) |
|
perror("dup2 stdin"); |
|
close(pin[0]); |
|
|
|
/* Redirect stdout. */ |
|
close(pout[0]); |
|
if (dup2(pout[1], 1) < 0) |
|
perror("dup2 stdout"); |
|
close(pout[1]); |
|
|
|
/* Redirect stderr. */ |
|
close(perr[0]); |
|
if (dup2(perr[1], 2) < 0) |
|
perror("dup2 stderr"); |
|
close(perr[1]); |
|
#else |
|
/* |
* Redirect stdin, stdout, and stderr. Stdin and stdout will |
* Redirect stdin, stdout, and stderr. Stdin and stdout will |
* use the same socket, as some programs (particularly rdist) |
* use the same socket, as some programs (particularly rdist) |
* seem to depend on it. |
* seem to depend on it. |
|
|
perror("dup2 stdin"); |
perror("dup2 stdin"); |
if (dup2(inout[0], 1) < 0) /* stdout (same as stdin) */ |
if (dup2(inout[0], 1) < 0) /* stdout (same as stdin) */ |
perror("dup2 stdout"); |
perror("dup2 stdout"); |
|
close(inout[0]); |
if (dup2(err[0], 2) < 0) /* stderr */ |
if (dup2(err[0], 2) < 0) /* stderr */ |
perror("dup2 stderr"); |
perror("dup2 stderr"); |
|
close(err[0]); |
|
#endif |
|
|
/* Do processing for the child (exec command etc). */ |
/* Do processing for the child (exec command etc). */ |
do_child(s, command); |
do_child(s, command); |
|
|
/* Set interactive/non-interactive mode. */ |
/* Set interactive/non-interactive mode. */ |
packet_set_interactive(s->display != NULL); |
packet_set_interactive(s->display != NULL); |
|
|
|
#ifdef USE_PIPES |
|
/* We are the parent. Close the child sides of the pipes. */ |
|
close(pin[0]); |
|
close(pout[1]); |
|
close(perr[1]); |
|
|
|
if (compat20) { |
|
if (s->is_subsystem) { |
|
close(perr[0]); |
|
perr[0] = -1; |
|
} |
|
session_set_fds(s, pin[1], pout[0], perr[0]); |
|
} else { |
|
/* Enter the interactive session. */ |
|
server_loop(pid, pin[1], pout[0], perr[0]); |
|
/* server_loop has closed pin[1], pout[0], and perr[0]. */ |
|
} |
|
#else |
/* We are the parent. Close the child sides of the socket pairs. */ |
/* We are the parent. Close the child sides of the socket pairs. */ |
close(inout[0]); |
close(inout[0]); |
close(err[0]); |
close(err[0]); |
|
|
server_loop(pid, inout[1], inout[1], err[1]); |
server_loop(pid, inout[1], inout[1], err[1]); |
/* server_loop has closed inout[1] and err[1]. */ |
/* server_loop has closed inout[1] and err[1]. */ |
} |
} |
|
#endif |
return 0; |
return 0; |
} |
} |
|
|