I got some code that prints to stdout, in pseudo code it looks like
int main(){
//allocate data
while(conditional){
char *string = makedata();
fprintf(stdout,"%s",string);
}
//cleanup
}
This works fine, if the conditional is toggled to zero, but if I pipe the output like
./a.out |head -n10 >dumped
Then the code never reaches the cleanup part, I don't understand how to check if the stdout gets closed.
Thanks
Your stdout hasn't been closed, so checking for that will be useless. Your program has received a SIGPIPE and exited. A SIGPIPE is delivered whenever your program writes to a pipe on which there are no readers. In your example, that happens when head
exits, closing its stdin.
You should ignore SIGPIPE if you want your program to continue. This code will ignore SIGPIPE:
(void)signal(SIGPIPE, SIG_IGN);
If you don't want to modify your program, you can arrange that something continues to read from the pipe, even after head
closes its input. 1
./a.out | ( head -n10 >dumped ; cat > /dev/null )
1: The shell example is valid for bash, maybe not for csh.
It is closed by killing the process with SIGPIPE
.
If you want to go on when your output is being ignored, then set up a SIG_IGN
handler for SIGPIPE
, and handle the error from the fprintf
(which will be delayed by buffering, so you cannot assume data that has been written has actually reached the user).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With