Now that we can use pipes for stdin/stdout/stderr there is no

longer a need to error out when there is no tty.  We just need
to make sure we don't try to use the tty fd if it is -1.
This commit is contained in:
Todd C. Miller
2010-05-18 17:43:10 -04:00
parent 55ef027d88
commit 6a2a182e0f

View File

@@ -121,7 +121,7 @@ static int foreground;
static char slavename[PATH_MAX];
static int suspend_parent(int signo, int fd, struct io_buffer *output);
static int suspend_parent(int signo, struct io_buffer *iobufs);
static void flush_output(struct io_buffer *iobufs);
static int perform_io(struct io_buffer *iobufs, fd_set *fdsr, fd_set *fdsw);
static void handler(int s);
@@ -138,12 +138,11 @@ void
script_setup(uid_t uid)
{
script_fds[SFD_USERTTY] = open(_PATH_TTY, O_RDWR|O_NOCTTY, 0);
if (script_fds[SFD_USERTTY] == -1)
errorx(1, "tty required for transcript support");
if (script_fds[SFD_USERTTY] != -1) {
if (!get_pty(&script_fds[SFD_MASTER], &script_fds[SFD_SLAVE],
slavename, sizeof(slavename), uid))
error(1, "Can't get pty");
}
}
/* Call I/O plugin tty input log method. */
@@ -264,6 +263,7 @@ log_stderr(char *buf, unsigned int n)
static void
check_foreground(void)
{
if (script_fds[SFD_USERTTY] != -1) {
foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == ppgrp;
if (foreground && !tty_initialized) {
if (term_copy(script_fds[SFD_USERTTY], script_fds[SFD_SLAVE])) {
@@ -271,6 +271,7 @@ check_foreground(void)
sync_ttysize(script_fds[SFD_USERTTY], script_fds[SFD_SLAVE]);
}
}
}
}
/*
@@ -278,7 +279,7 @@ check_foreground(void)
* Returns SIGUSR1 if the child should be resume in foreground else SIGUSR2.
*/
static int
suspend_parent(int signo, int fd, struct io_buffer *iobufs)
suspend_parent(int signo, struct io_buffer *iobufs)
{
sigaction_t sa, osa;
int n, oldmode = ttymode, rval = 0;
@@ -534,9 +535,11 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
sigaction(SIGTERM, &sa, NULL);
if (log_io) {
if (script_fds[SFD_USERTTY] != -1) {
sa.sa_flags = SA_RESTART;
sa.sa_handler = sigwinch;
sigaction(SIGWINCH, &sa, NULL);
}
/* So we can block tty-generated signals */
sigemptyset(&ttyblock);
@@ -546,9 +549,6 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
sigaddset(&ttyblock, SIGTTIN);
sigaddset(&ttyblock, SIGTTOU);
/* Are we the foreground process? */
foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == ppgrp;
/*
* Setup stdin/stdout/stderr for child, to be duped after forking.
*/
@@ -557,6 +557,7 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
script_fds[SFD_STDERR] = script_fds[SFD_SLAVE];
/* Copy /dev/tty -> pty master */
if (script_fds[SFD_USERTTY] != -1) {
iobufs = io_buf_new(script_fds[SFD_USERTTY], script_fds[SFD_MASTER],
log_ttyin, iobufs);
@@ -564,6 +565,10 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
iobufs = io_buf_new(script_fds[SFD_MASTER], script_fds[SFD_USERTTY],
log_ttyout, iobufs);
/* Are we the foreground process? */
foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == ppgrp;
}
/*
* If either stdin, stdout or stderr is not a tty we use a pipe
* to interpose ourselves instead of duping the pty fd.
@@ -790,7 +795,7 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
if (WIFSTOPPED(cstat->val)) {
/* Suspend parent and tell child how to resume on return. */
sudo_debug(8, "child stopped, suspending parent");
n = suspend_parent(WSTOPSIG(cstat->val), script_fds[SFD_USERTTY], iobufs);
n = suspend_parent(WSTOPSIG(cstat->val), iobufs);
recvsig[n] = TRUE;
continue;
} else {
@@ -826,25 +831,31 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
if (log_io) {
/* Flush any remaining output (the plugin already got it) */
if (script_fds[SFD_USERTTY] != -1) {
n = fcntl(script_fds[SFD_USERTTY], F_GETFL, 0);
if (n != -1 && ISSET(n, O_NONBLOCK)) {
CLR(n, O_NONBLOCK);
(void) fcntl(script_fds[SFD_USERTTY], F_SETFL, n);
}
}
flush_output(iobufs);
if (script_fds[SFD_USERTTY] != -1) {
do {
n = term_restore(script_fds[SFD_USERTTY], 0);
} while (!n && errno == EINTR);
}
if (cstat->type == CMD_WSTATUS && WIFSIGNALED(cstat->val)) {
int signo = WTERMSIG(cstat->val);
if (signo && signo != SIGINT && signo != SIGPIPE) {
char *reason = strsignal(signo);
write(script_fds[SFD_USERTTY], reason, strlen(reason));
n = script_fds[SFD_USERTTY] != -1 ?
script_fds[SFD_USERTTY] : STDOUT_FILENO;
write(n, reason, strlen(reason));
if (WCOREDUMP(cstat->val))
write(script_fds[SFD_USERTTY], " (core dumped)", 14);
write(script_fds[SFD_USERTTY], "\n", 1);
write(n, " (core dumped)", 14);
write(n, "\n", 1);
}
}
}
@@ -928,7 +939,9 @@ script_child(const char *path, char *argv[], char *envp[], int backchannel, int
int alive = TRUE;
/* Close unused fds. */
if (script_fds[SFD_MASTER] != -1)
close(script_fds[SFD_MASTER]);
if (script_fds[SFD_USERTTY] != -1)
close(script_fds[SFD_USERTTY]);
/* Reset signal handlers. */
@@ -971,6 +984,7 @@ script_child(const char *path, char *argv[], char *envp[], int backchannel, int
# endif
setpgrp(0, 0);
#endif
if (script_fds[SFD_SLAVE] != -1) {
#ifdef TIOCSCTTY
if (ioctl(script_fds[SFD_SLAVE], TIOCSCTTY, NULL) != 0)
error(1, "unable to set controlling tty");
@@ -979,6 +993,7 @@ script_child(const char *path, char *argv[], char *envp[], int backchannel, int
if ((n = open(slavename, O_RDWR)) >= 0)
close(n);
#endif
}
/*
* If stdin/stdout is not a tty, start command in the background
@@ -1237,6 +1252,7 @@ script_run(const char *path, char *argv[], char *envp[], int rbac_enabled)
}
/* We have guaranteed that the slave fd > 3 */
if (script_fds[SFD_SLAVE] != -1)
close(script_fds[SFD_SLAVE]);
#ifdef HAVE_SELINUX