Changeset View
Standalone View
bin/sh/jobs.c
Show First 20 Lines • Show All 905 Lines • ▼ Show 20 Lines | if (pid == -1) { | ||||
INTON; | INTON; | ||||
error("Cannot fork: %s", strerror(errno)); | error("Cannot fork: %s", strerror(errno)); | ||||
} | } | ||||
if (pid == 0) { | if (pid == 0) { | ||||
struct job *p; | struct job *p; | ||||
int wasroot; | int wasroot; | ||||
int i; | int i; | ||||
if (Sflag) | |||||
(void)setsid(); | |||||
0mp: Shouldn't we check the return value for errors? | |||||
jillesUnsubmitted Not Done Inline ActionsIt would feel safer to add this further down (but still before the setpgid() from job control). In particular, doing things that may throw exceptions before the handler = &main_handler; below may cause exception handlers to be run twice (in parent and child). This might be problematic because, for example, histedit.c has an exception handler that deletes a temporary file. Although system calls such as setsid() do not throw exceptions, a surprising amount of code in sh may throw exceptions. jilles: It would feel safer to add this further down (but still before the `setpgid()` from job… | |||||
jillesUnsubmitted Not Done Inline ActionsDoing this here directly after fork() ensures that setsid() will not fail, but in some situations it will be poorly predictable whether a new session will be created, since sh treats this as an implementation detail. For example, a final subshell or program may or may not be executed in a new process: $ sh -c 'ps -o comm= -p $$' ps $ sh -c 'trap "" 0; ps -o comm= -p $$' ps $ sh -c 'trap : 0; ps -o comm= -p $$' sh $ sh -c ':; (:; ps -o comm= -p $$)' ps $ sh -c 'if :; then ps -o comm= -p $$; fi' ps certain simple commands may use vfork() instead of fork(), and command substitutions may be executed entirely in-process, using vfork() or using fork(). This is why POSIX talks about "shell environments" and not "child processes" when discussing the effect of () and the like. One completely predictable fork() is the one caused by the running something in the background using the & control operator. With non-interactive job control this is a fixed pattern set -m; X & set +m. A new option might only be active in this predictable case. jilles: Doing this here directly after `fork()` ensures that `setsid()` will not fail, but in some… | |||||
jillesUnsubmitted Not Done Inline ActionsSince there is no way to move a process to another existing session and all members of a pipeline are children of the main shell process, a command like set -o setsid; A | B | C & will unavoidably create three sessions. This differs from job control where the shell puts A, B and C into the same process group. On the other hand, set -o setsid; (A | B | C) & adds an intermediate process which will allow A, B and C to be in a single session. This comment does not suggest an immediate direction in this. jilles: Since there is no way to move a process to another existing session and all members of a… | |||||
TRACE(("Child shell %d\n", (int)getpid())); | TRACE(("Child shell %d\n", (int)getpid())); | ||||
wasroot = rootshell; | wasroot = rootshell; | ||||
rootshell = 0; | rootshell = 0; | ||||
handler = &main_handler; | handler = &main_handler; | ||||
closescript(); | closescript(); | ||||
INTON; | INTON; | ||||
forcelocal = 0; | forcelocal = 0; | ||||
clear_traps(); | clear_traps(); | ||||
▲ Show 20 Lines • Show All 656 Lines • Show Last 20 Lines |
Shouldn't we check the return value for errors?