static sig_atomic_t alive = 1;
static sig_atomic_t recvsig = 0;
static sig_atomic_t ttymode = TERM_COOKED;
-static sig_atomic_t foreground = 0;
static sig_atomic_t tty_initialized = 0;
static sigset_t ttyblock;
static pid_t parent, child;
static int child_status;
+static int foreground;
static char slavename[PATH_MAX];
static void script_child __P((char *path, char *argv[], int, int));
static void script_run __P((char *path, char *argv[], int));
static void sigchild __P((int s));
-static void sigcont __P((int s));
static void sigwinch __P((int s));
static void sync_winsize __P((int src, int dst));
sigprocmask(SIG_SETMASK, &omask, NULL);
}
+static void
+check_foreground()
+{
+ foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == parent;
+ if (foreground && !tty_initialized) {
+ if (term_copy(script_fds[SFD_USERTTY], script_fds[SFD_SLAVE], 0)) {
+ tty_initialized = 1;
+ sync_winsize(script_fds[SFD_USERTTY], script_fds[SFD_SLAVE]);
+ }
+ }
+}
+
/*
* Suspend sudo if the underlying command is suspended.
* Returns SIGUSR1 if the child should be resume in foreground else SIGUSR2.
* If we are the foreground process, just resume the child.
* Otherwise, re-send the signal with the handler disabled.
*/
+ if (!foreground)
+ check_foreground();
if (foreground) {
if (ttymode != TERM_RAW) {
do {
#endif
kill(parent, signo);
+ /* Check foreground/background status on resume. */
+ check_foreground();
+
/*
* Only modify term if we are foreground process and either
* the old tty mode was not cooked or child got SIGTT{IN,OU}
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
- /* To update foreground/background state. */
- sa.sa_handler = sigcont;
- sigaction(SIGCONT, &sa, NULL);
-
/* Signals to relay from parent to child. */
sa.sa_flags = 0; /* do not restart syscalls for these */
sa.sa_handler = handler;
zero_bytes(&input, sizeof(input));
zero_bytes(&output, sizeof(output));
while (alive) {
- /* XXX */
+ /* XXX - racey */
if (!relaysig && recvsig != SIGCHLD) {
relaysig = recvsig;
recvsig = 0;
killpg(child, SIGCONT);
break;
default:
- /* XXX - warn? */
+ warningx("unexpected signal from child: %d", signo);
break;
}
}
#endif
}
-/*
- * Handler for SIGCONT in parent
- */
-static void
-sigcont(s)
- int s;
-{
- int serrno = errno;
-
- /* Did we get continued in the foreground or background? */
- foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == parent;
-
- if (foreground && !tty_initialized) {
- if (term_copy(script_fds[SFD_USERTTY], script_fds[SFD_SLAVE], 0)) {
- tty_initialized = 1;
- sync_winsize(script_fds[SFD_USERTTY], script_fds[SFD_SLAVE]);
- }
- }
-
- errno = serrno;
-}
-
/*
* Handler for SIGCHLD in parent
*/