cstat->val = errno;
return -1;
case 0:
- /* child continues */
+ /* child continues without controlling terminal */
+ (void)setpgid(0, 0);
break;
default:
- /* parent exits */
- exit(0);
+ /* parent exits (but does not flush buffers) */
+ _exit(0);
}
}
#ifdef _PATH_SUDO_IO_LOGDIR
log_io = def_log_output || def_log_input || def_use_pty;
if (log_io) {
- if (!bgmode)
- pty_setup(uid);
+ pty_setup(uid);
io_log_open();
dowait = TRUE;
}
*/
#ifdef _PATH_SUDO_IO_LOGDIR
if (log_io)
- child = fork_pty(path, argv, envp, sv, rbac_enabled, &maxfd);
+ child = fork_pty(path, argv, envp, sv, rbac_enabled, bgmode, &maxfd);
else
#endif
child = fork_cmnd(path, argv, envp, sv, rbac_enabled);
* Returns the child pid.
*/
int
-fork_pty(path, argv, envp, sv, rbac_enabled, maxfd)
+fork_pty(path, argv, envp, sv, rbac_enabled, bgmode, maxfd)
const char *path;
char *argv[];
char *envp[];
int sv[2];
int rbac_enabled;
+ int bgmode;
int *maxfd;
{
struct command_status cstat;
/*
* Setup stdin/stdout/stderr for child, to be duped after forking.
+ * In background mode there is no stdin.
*/
- io_fds[SFD_STDIN] = io_fds[SFD_SLAVE];
+ if (!bgmode)
+ io_fds[SFD_STDIN] = io_fds[SFD_SLAVE];
io_fds[SFD_STDOUT] = io_fds[SFD_SLAVE];
io_fds[SFD_STDERR] = io_fds[SFD_SLAVE];
- /* Copy /dev/tty -> pty master */
if (io_fds[SFD_USERTTY] != -1) {
- iobufs = io_buf_new(io_fds[SFD_USERTTY], io_fds[SFD_MASTER],
- log_ttyin, iobufs);
+ /* Read from /dev/tty, write to pty master */
+ if (!bgmode) {
+ iobufs = io_buf_new(io_fds[SFD_USERTTY], io_fds[SFD_MASTER],
+ log_ttyin, iobufs);
+ }
- /* Copy pty master -> /dev/tty */
+ /* Read from pty master, write to /dev/tty */
iobufs = io_buf_new(io_fds[SFD_MASTER], io_fds[SFD_USERTTY],
log_ttyout, iobufs);
/* exec_pty.c */
int fork_pty __P((const char *path, char *argv[], char *envp[], int sv[],
- int rbac_enabled, int *maxfd));
+ int rbac_enabled, int bgmode, int *maxfd));
int perform_io __P((fd_set *fdsr, fd_set *fdsw, struct command_status *cstat));
int suspend_parent __P((int signo));
void fd_set_iobs __P((fd_set *fdsr, fd_set *fdsw));