Fix sh(1) changing foreground group when non-interactive.
This commit is contained in:
parent
0f348c192b
commit
07dd21146b
36
sh/sh.c
36
sh/sh.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2011-2016, 2022 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -1295,7 +1295,7 @@ struct execute_result execute(char** tokens,
|
||||||
// foreground process group, but bar dies prior to foo's tcsetpgrp
|
// foreground process group, but bar dies prior to foo's tcsetpgrp
|
||||||
// call, because then the shell would run tcsetpgrp to take back
|
// call, because then the shell would run tcsetpgrp to take back
|
||||||
// control, and only then would foo do its tcsetpgrp call.
|
// control, and only then would foo do its tcsetpgrp call.
|
||||||
while ( foreground_shell && pgid == -1 && tcgetpgrp(0) != childpid )
|
while ( interactive && pgid == -1 && tcgetpgrp(0) != childpid )
|
||||||
sched_yield();
|
sched_yield();
|
||||||
|
|
||||||
struct execute_result result;
|
struct execute_result result;
|
||||||
|
@ -1306,7 +1306,7 @@ struct execute_result execute(char** tokens,
|
||||||
}
|
}
|
||||||
|
|
||||||
setpgid(0, pgid != -1 ? pgid : 0);
|
setpgid(0, pgid != -1 ? pgid : 0);
|
||||||
if ( foreground_shell && pgid == -1 )
|
if ( interactive && pgid == -1 )
|
||||||
{
|
{
|
||||||
sigset_t oldset, sigttou;
|
sigset_t oldset, sigttou;
|
||||||
sigemptyset(&sigttou);
|
sigemptyset(&sigttou);
|
||||||
|
@ -1491,12 +1491,15 @@ readcmd:
|
||||||
// as that may have side effects if a process checks for this
|
// as that may have side effects if a process checks for this
|
||||||
// behavior and then unexpectedly the shell takes back support
|
// behavior and then unexpectedly the shell takes back support
|
||||||
// without the usual ^Z mechanism.
|
// without the usual ^Z mechanism.
|
||||||
sigset_t oldset, sigttou;
|
if ( interactive )
|
||||||
sigemptyset(&sigttou);
|
{
|
||||||
sigaddset(&sigttou, SIGTTOU);
|
sigset_t oldset, sigttou;
|
||||||
sigprocmask(SIG_BLOCK, &sigttou, &oldset);
|
sigemptyset(&sigttou);
|
||||||
tcsetpgrp(0, getpgid(0));
|
sigaddset(&sigttou, SIGTTOU);
|
||||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
sigprocmask(SIG_BLOCK, &sigttou, &oldset);
|
||||||
|
tcsetpgrp(0, getpgid(0));
|
||||||
|
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||||
|
}
|
||||||
pgid = -1;
|
pgid = -1;
|
||||||
status = 0;
|
status = 0;
|
||||||
goto readcmd;
|
goto readcmd;
|
||||||
|
@ -1520,12 +1523,15 @@ readcmd:
|
||||||
status = 1;
|
status = 1;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
sigset_t oldset, sigttou;
|
if ( interactive )
|
||||||
sigemptyset(&sigttou);
|
{
|
||||||
sigaddset(&sigttou, SIGTTOU);
|
sigset_t oldset, sigttou;
|
||||||
sigprocmask(SIG_BLOCK, &sigttou, &oldset);
|
sigemptyset(&sigttou);
|
||||||
tcsetpgrp(0, getpgid(0));
|
sigaddset(&sigttou, SIGTTOU);
|
||||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
sigprocmask(SIG_BLOCK, &sigttou, &oldset);
|
||||||
|
tcsetpgrp(0, getpgid(0));
|
||||||
|
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||||
|
}
|
||||||
if ( WIFSIGNALED(exitstatus) && WTERMSIG(exitstatus) == SIGINT )
|
if ( WIFSIGNALED(exitstatus) && WTERMSIG(exitstatus) == SIGINT )
|
||||||
printf("^C\n");
|
printf("^C\n");
|
||||||
else if ( WIFSIGNALED(exitstatus) && WTERMSIG(exitstatus) != SIGPIPE )
|
else if ( WIFSIGNALED(exitstatus) && WTERMSIG(exitstatus) != SIGPIPE )
|
||||||
|
|
Loading…
Reference in New Issue