Update foreground/background status in SIGCONT handler in parent process.
This commit is contained in:
33
script.c
33
script.c
@@ -94,6 +94,7 @@ static int script_fds[6];
|
|||||||
|
|
||||||
static sig_atomic_t alive = 1;
|
static sig_atomic_t alive = 1;
|
||||||
static sig_atomic_t suspended = 0;
|
static sig_atomic_t suspended = 0;
|
||||||
|
static sig_atomic_t foreground = 0;
|
||||||
|
|
||||||
static pid_t parent, child;
|
static pid_t parent, child;
|
||||||
static int child_status;
|
static int child_status;
|
||||||
@@ -104,6 +105,7 @@ static void script_child __P((char *path, char *argv[], int, int));
|
|||||||
static void script_run __P((char *path, char *argv[], int));
|
static void script_run __P((char *path, char *argv[], int));
|
||||||
static void sync_winsize __P((int src, int dst));
|
static void sync_winsize __P((int src, int dst));
|
||||||
static void sigchild __P((int s));
|
static void sigchild __P((int s));
|
||||||
|
static void sigcont __P((int s));
|
||||||
static void sigfgbg __P((int s));
|
static void sigfgbg __P((int s));
|
||||||
static void sigtstp __P((int s));
|
static void sigtstp __P((int s));
|
||||||
static void sigwinch __P((int s));
|
static void sigwinch __P((int s));
|
||||||
@@ -362,7 +364,7 @@ script_execv(path, argv)
|
|||||||
sigaction_t sa, osa;
|
sigaction_t sa, osa;
|
||||||
struct script_buf input, output;
|
struct script_buf input, output;
|
||||||
struct timeval now, then;
|
struct timeval now, then;
|
||||||
int foreground, n, nready, exitcode = 1;
|
int n, nready, exitcode = 1;
|
||||||
fd_set *fdsr, *fdsw;
|
fd_set *fdsr, *fdsw;
|
||||||
FILE *idfile;
|
FILE *idfile;
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
@@ -384,6 +386,10 @@ script_execv(path, argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Are we the foreground process? */
|
||||||
|
parent = getpid(); /* so child can pass signals back to us */
|
||||||
|
foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == parent;
|
||||||
|
|
||||||
/* Setup signal handlers window size changes and child exit */
|
/* Setup signal handlers window size changes and child exit */
|
||||||
zero_bytes(&sa, sizeof(sa));
|
zero_bytes(&sa, sizeof(sa));
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
@@ -393,16 +399,16 @@ script_execv(path, argv)
|
|||||||
sa.sa_handler = sigchild;
|
sa.sa_handler = sigchild;
|
||||||
sigaction(SIGCHLD, &sa, NULL);
|
sigaction(SIGCHLD, &sa, NULL);
|
||||||
|
|
||||||
|
/* To update foreground/background state. */
|
||||||
|
sa.sa_handler = sigcont;
|
||||||
|
sigaction(SIGCONT, &sa, NULL);
|
||||||
|
|
||||||
/* Handler for tty stop signals */
|
/* Handler for tty stop signals */
|
||||||
sa.sa_handler = sigtstp;
|
sa.sa_handler = sigtstp;
|
||||||
sigaction(SIGTSTP, &sa, NULL);
|
sigaction(SIGTSTP, &sa, NULL);
|
||||||
sigaction(SIGTTIN, &sa, NULL);
|
sigaction(SIGTTIN, &sa, NULL);
|
||||||
sigaction(SIGTTOU, &sa, NULL);
|
sigaction(SIGTTOU, &sa, NULL);
|
||||||
|
|
||||||
/* Are we the foreground process? */
|
|
||||||
parent = getpid(); /* so child can pass signals back to us */
|
|
||||||
foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == parent;
|
|
||||||
|
|
||||||
/* Only set tty to raw mode if we are the foreground process. */
|
/* Only set tty to raw mode if we are the foreground process. */
|
||||||
if (foreground) {
|
if (foreground) {
|
||||||
do {
|
do {
|
||||||
@@ -504,7 +510,6 @@ script_execv(path, argv)
|
|||||||
* If we are the foreground process, just resume the child.
|
* If we are the foreground process, just resume the child.
|
||||||
* Otherwise, re-send the signal with the handler disabled.
|
* Otherwise, re-send the signal with the handler disabled.
|
||||||
*/
|
*/
|
||||||
foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == parent;
|
|
||||||
if (foreground) {
|
if (foreground) {
|
||||||
suspended = 0;
|
suspended = 0;
|
||||||
/* Set tty to raw mode and tell child it is in foregound. */
|
/* Set tty to raw mode and tell child it is in foregound. */
|
||||||
@@ -534,7 +539,6 @@ script_execv(path, argv)
|
|||||||
* If we were suspended due to tty I/O and sudo is still in
|
* If we were suspended due to tty I/O and sudo is still in
|
||||||
* the background, re-suspend.
|
* the background, re-suspend.
|
||||||
*/
|
*/
|
||||||
foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == parent;
|
|
||||||
if (!foreground && (suspended == SIGTTOU || suspended == SIGTTIN))
|
if (!foreground && (suspended == SIGTTOU || suspended == SIGTTIN))
|
||||||
goto suspend;
|
goto suspend;
|
||||||
|
|
||||||
@@ -886,6 +890,21 @@ sync_winsize(src, dst)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handler for SIGCONT in parent
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sigcont(s)
|
||||||
|
int s;
|
||||||
|
{
|
||||||
|
int serrno = errno;
|
||||||
|
|
||||||
|
/* Did we get continued in the foreground or background? */
|
||||||
|
foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == parent;
|
||||||
|
|
||||||
|
errno = serrno;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Signal handler for SIGUSR[12] in child
|
* Signal handler for SIGUSR[12] in child
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user