* we fact that we have two different controlling terminals to deal with.
*/
int
-sudo_execve(path, argv, envp, uid, cstat, dowait)
+sudo_execve(path, argv, envp, uid, cstat, dowait, bgmode)
const char *path;
char *argv[];
char *envp[];
uid_t uid;
struct command_status *cstat;
int dowait;
+ int bgmode;
{
sigaction_t sa;
fd_set *fdsr, *fdsw;
int maxfd, n, nready, status, sv[2];
int rbac_enabled = 0;
- int log_io = 0;
+ int log_io;
pid_t child;
- cstat->type = CMD_INVALID;
+ /* If running in background mode, fork and exit. */
+ if (bgmode) {
+ switch (fork()) {
+ case -1:
+ cstat->type = CMD_ERRNO;
+ cstat->val = errno;
+ return -1;
+ case 0:
+ /* child continues */
+ break;
+ default:
+ /* parent exits */
+ exit(0);
+ }
+ }
#ifdef _PATH_SUDO_IO_LOGDIR
log_io = def_log_output || def_log_input || def_use_pty;
if (log_io) {
- pty_setup(uid);
+ if (!bgmode)
+ pty_setup(uid);
io_log_open();
dowait = TRUE;
}
/* Suspend self and continue child when we resume. */
sa.sa_handler = SIG_DFL;
sigaction(signo, &sa, &osa);
- killpg(ppgrp, signo);
+ if (killpg(ppgrp, signo) != 0)
+ warning("killpg(%d, %d)", ppgrp, signo);
/* Check foreground/background status on resume. */
check_foreground();
* to interpose ourselves instead of duping the pty fd.
*/
memset(io_pipe, 0, sizeof(io_pipe));
- if (!isatty(STDIN_FILENO)) {
+ if (io_fds[SFD_STDIN] == -1 || !isatty(STDIN_FILENO)) {
pipeline = TRUE;
if (pipe(io_pipe[STDIN_FILENO]) != 0)
error(1, "unable to create pipe");
log_stdin, iobufs);
io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0];
}
- if (!isatty(STDOUT_FILENO)) {
+ if (io_fds[SFD_STDOUT] == -1 || !isatty(STDOUT_FILENO)) {
pipeline = TRUE;
if (pipe(io_pipe[STDOUT_FILENO]) != 0)
error(1, "unable to create pipe");
log_stdout, iobufs);
io_fds[SFD_STDOUT] = io_pipe[STDOUT_FILENO][1];
}
- if (!isatty(STDERR_FILENO)) {
+ if (io_fds[SFD_STDERR] == -1 || !isatty(STDERR_FILENO)) {
if (pipe(io_pipe[STDERR_FILENO]) != 0)
error(1, "unable to create pipe");
iobufs = io_buf_new(io_pipe[STDERR_FILENO][0], STDERR_FILENO,
goto done;
}
- if (ISSET(sudo_mode, MODE_BACKGROUND)) {
- switch (fork()) {
- case -1:
- warning("fork");
- goto done;
- case 0:
- /* child continues */
- break;
- default:
- /* parent exists */
- exit(0);
- }
- }
-
rval = TRUE;
done:
cstat.type = CMD_INVALID;
cstat.val = 0;
- sudo_execve(path, argv, envp, uid, &cstat, dowait);
+ sudo_execve(path, argv, envp, uid, &cstat, dowait,
+ ISSET(sudo_mode, MODE_BACKGROUND));
switch (cstat.type) {
case CMD_ERRNO:
/* exec.c */
int sudo_execve __P((const char *path, char *argv[], char *envp[], uid_t uid,
- struct command_status *cstat, int dowait));
+ struct command_status *cstat, int dowait, int bgmode));
int my_execve __P((const char *path, char *argv[], char *envp[]));
/* exec_pty.c */