[Bug manual/25555] New: Not closing read-en of pipe avoid kernel sending SIGPIPE to previous process in pipeline
abarthel at student dot 42.fr
sourceware-bugzilla@sourceware.org
Fri Feb 14 12:10:00 GMT 2020
https://sourceware.org/bugzilla/show_bug.cgi?id=25555
Bug ID: 25555
Summary: Not closing read-en of pipe avoid kernel sending
SIGPIPE to previous process in pipeline
Product: glibc
Version: unspecified
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: manual
Assignee: unassigned at sourceware dot org
Reporter: abarthel at student dot 42.fr
CC: mtk.manpages at gmail dot com
Target Milestone: ---
Overview: In section 28.5.3 Launching Jobs of Libc Manual, nor launch_job nor
launch_process function close read-end of pipe process which leads the kernel
not to send SIGPIPE to the previous process in the pipeline.
Steps to Reproduce: Executing launch_job and launch_process together in a
program that runs a pipeline such as "ls -lR / | hostname".
Actual Results: When doing so, "ls -lR /" does not receive SIGPIPE from the
kernel when "hostname" ends but instead it is suspended. In this situation we
need to kill manually "ls -lR /" which is suspended.
Expected Results: When running "ls -lR / | hostname", as soon as hostname ends,
"ls -lR /" should receive SIGPIPE and exit.
Additional Information: I suggest to add a single line to launch_job to ensure
read-end of pipe will actually be closed, avoiding leaving a pipe in a single
process ("ls" in the example).
void
launch_job (job *j, int foreground)
{
process *p;
pid_t pid;
int mypipe[2], infile, outfile;
infile = j->stdin;
for (p = j->first_process; p; p = p->next)
{
/* Set up pipes, if necessary. */
if (p->next)
{
if (pipe (mypipe) < 0)
{
perror ("pipe");
exit (1);
}
outfile = mypipe[1];
}
else
outfile = j->stdout;
/* Fork the child processes. */
pid = fork ();
if (pid == 0)
{
/* This is the child process. */
if (infile != mypipe[0]) /* Close read-end of pipe */
close(mypipe[0]);
launch_process (p, j->pgid, infile,
outfile, j->stderr, foreground);
}
else if (pid < 0)
{
/* The fork failed. */
perror ("fork");
exit (1);
}
else
{
/* This is the parent process. */
p->pid = pid;
if (shell_is_interactive)
{
if (!j->pgid)
j->pgid = pid;
setpgid (pid, j->pgid);
}
}
/* Clean up after pipes. */
if (infile != j->stdin)
close (infile);
if (outfile != j->stdout)
close (outfile);
infile = mypipe[0];
}
format_job_info (j, "launched");
if (!shell_is_interactive)
wait_for_job (j);
else if (foreground)
put_job_in_foreground (j, 0);
else
put_job_in_background (j, 0);
}
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the Glibc-bugs
mailing list