Save the controlling tty process group before suspending so we can
restore it when we resume. Fixes job control problems on Linux caused by the previous attemp to fix resuming a shell when I/O logging not enabled.
This commit is contained in:
34
src/exec.c
34
src/exec.c
@@ -444,9 +444,21 @@ handle_signals(int fd, pid_t child, int log_io, struct command_status *cstat)
|
|||||||
/* If not logging I/O and child has exited we are done. */
|
/* If not logging I/O and child has exited we are done. */
|
||||||
if (!log_io) {
|
if (!log_io) {
|
||||||
if (WIFSTOPPED(status)) {
|
if (WIFSTOPPED(status)) {
|
||||||
/* Child may not have privs to suspend us itself. */
|
/*
|
||||||
|
* Save the controlling terminal's process group
|
||||||
|
* so we can restore it after we resume.
|
||||||
|
*/
|
||||||
|
pid_t saved_pgrp = (pid_t)-1;
|
||||||
|
int fd = open(_PATH_TTY, O_RDWR|O_NOCTTY, 0);
|
||||||
|
if (fd != -1)
|
||||||
|
saved_pgrp = tcgetpgrp(fd);
|
||||||
if (kill(getpid(), WSTOPSIG(status)) != 0)
|
if (kill(getpid(), WSTOPSIG(status)) != 0)
|
||||||
warning("kill(%d, %d)", getpid(), WSTOPSIG(status));
|
warning("kill(%d, %d)", getpid(), WSTOPSIG(status));
|
||||||
|
if (fd != -1) {
|
||||||
|
if (saved_pgrp != (pid_t)-1)
|
||||||
|
(void)tcsetpgrp(fd, saved_pgrp);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Child has exited, we are done. */
|
/* Child has exited, we are done. */
|
||||||
cstat->type = CMD_WSTATUS;
|
cstat->type = CMD_WSTATUS;
|
||||||
@@ -462,24 +474,10 @@ handle_signals(int fd, pid_t child, int log_io, struct command_status *cstat)
|
|||||||
schedule_signal(signo);
|
schedule_signal(signo);
|
||||||
} else {
|
} else {
|
||||||
/* Nothing listening on sv[0], send directly. */
|
/* Nothing listening on sv[0], send directly. */
|
||||||
if (signo == SIGALRM) {
|
if (signo == SIGALRM)
|
||||||
terminate_child(child, FALSE);
|
terminate_child(child, FALSE);
|
||||||
} else {
|
else if (kill(child, signo) != 0)
|
||||||
if (signo == SIGCONT) {
|
warning("kill(%d, %d)", child, signo);
|
||||||
/*
|
|
||||||
* Before continuing the child, make it the foreground
|
|
||||||
* pgrp if possible. Fixes resuming a shell.
|
|
||||||
*/
|
|
||||||
int fd = open(_PATH_TTY, O_RDWR|O_NOCTTY, 0);
|
|
||||||
if (fd != -1) {
|
|
||||||
if (tcgetpgrp(fd) == getpgrp())
|
|
||||||
(void)tcsetpgrp(fd, child);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (kill(child, signo) != 0)
|
|
||||||
warning("kill(%d, %d)", child, signo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user