Close stdin/out after child is forked
Testcase: { sleep 1; yes | head -n99999; } | strace -o/dev/null sh -c 'exec <&-; sleep 9' The writer (head) will be able to perform writes to write end of the pipe. With strace call removed, head will immediately get SIGPIPE. This change fixes this: now writer immediately gets SIGPIPE with strace too. * strace.c (startup_child): Close stdin/out and reopen them to /dev/null. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
This commit is contained in:
21
strace.c
21
strace.c
@ -1353,6 +1353,27 @@ startup_child(char **argv)
|
||||
* to create a genuine separate stack and execute on it.
|
||||
*/
|
||||
}
|
||||
/*
|
||||
* A case where straced process is part of a pipe:
|
||||
* { sleep 1; yes | head -n99999; } | strace -o/dev/null sh -c 'exec <&-; sleep 9'
|
||||
* If strace won't close its fd#0, closing it in tracee is not enough:
|
||||
* the pipe is still open, it has a reader. Thus, "head" will not get its
|
||||
* SIGPIPE at once, on the first write.
|
||||
*
|
||||
* Preventing it by closing strace's stdin/out.
|
||||
* (Don't leave fds 0 and 1 closed, this is bad practice: future opens
|
||||
* will reuse them, unexpectedly making a newly opened object "stdin").
|
||||
*/
|
||||
close(0);
|
||||
if (open("/dev/null", O_RDWR) != 0) /* /dev not populated? */
|
||||
if (open("/", O_RDONLY) != 0) /* shouldn't happen... */
|
||||
perror_msg_and_die("Can't open '/'");
|
||||
dup2(0, 1);
|
||||
#if 0
|
||||
/* A good idea too, but we sometimes need to print error messages */
|
||||
if (shared_log != stderr)
|
||||
dup2(0, 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_SEIZE
|
||||
|
Reference in New Issue
Block a user