Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Broken pipe no longer ends programs?

When you pipe two process and kill the one at the "output" of the pipe, the first process used to receive the "Broken Pipe" signal, which usually terminated it aswell. E.g. running

$> do_something_intensive | less

and then exiting less used to return you immediately to a responsive shell, on a SuSE8 or former releases. when i'm trying that today, do_something_intensive is obviously still running until i kill it manually. It seems that something has changed (glib ? shell ?) that makes program ignore "broken pipes" ...

Anyone of you has hints on this ? how to restore the former behaviour ? why it has been changed (or why it always existed multiple semantics) ?

edit : further tests (using strace) reveal that "SIGPIPE" is generated, but that the program is not interrupted. A simple

#include <stdio.h>
int main() 
{
   while(1) printf("dumb test\n");
   exit(0);
}

will go on with an endless

--- SIGPIPE (Broken pipe) @ 0 (0) ---
write(1, "dumb test\ndumb test\ndumb test\ndu"..., 1024) = -1 EPIPE (Broken pipe)

when less is killed. I could for sure program a signal handler in my program and ensure it terminates, but i'm more looking for some environment variable or a shell option that would force programs to terminate on SIGPIPE

edit again: it seems to be a tcsh-specific issue (bash handles it properly) and terminal-dependent (Eterm 0.9.4)

like image 520
PypeBros Avatar asked Sep 19 '08 15:09

PypeBros


2 Answers

Well, if there is an attempt to write to a pipe after the reader has gone away, a SIGPIPE signal gets generated. The application has the ability to catch this signal, but if it doesn't, the process is killed.

The SIGPIPE won't be generated until the calling process attempts to write, so if there's no more output, it won't be generated.

like image 67
Daniel Papasian Avatar answered Nov 13 '22 01:11

Daniel Papasian


Has "do something intensive" changed at all?

As Daniel has mentioned SIGPIPE is not a magic "your pipe went away" signal but rather a "nice try, you can no longer read/write that pipe" signal.

If you have control of "do something intensive" you could change it to write out some "progress indicator" output as it spins. This would raise the SIGPIPE in a timely fashion.

like image 45
Frosty Avatar answered Nov 13 '22 03:11

Frosty