Broken pipe error(SIGPIPE)

  • SIGPIPE is the “broken pipe” signal that the kernel generates when a process writes to a pipe that has been closed by the reader, by default this causes the process terminates.
  • This behavior is useful for typical cases of running processes in pipelines.
  • A typical example to understand this is foo | bar, where foo’s output is given as input to bar.
  • It may be the case that the process bar dies, then there is no point in running process foo and producing output.
  • This can happen either bar has failed or does not need input and hence closes its end.
  • Thus the SIGPIPE notifies the writer that the reader process has died or closed its end and hence the writer can close its end too and do not produce output any further.
  • SIGPIPE can be received if the client is writing to the socket, even after having received a RST from the server.

Sample code:

  • There is a client and server and the client writes a message “hello” five times at an interval of 5 seconds, the server reads the first message and closes the pipe. This terminates the client process when it tries to write.
  • And at the same time signal, SIGPIPE can be ignored to make sure the client does not terminate until five attempts even if the server process has close its end.
  • Ideally, SIGPIPE should not be ignored as it allows a client to produce output even when a server has died or closed its end.

client.c

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>

#define FIFO_FILE "MYFIFO"

int main() {

   //signal(SIGPIPE, SIG_IGN);
   
   mkfifo (FIFO_FILE, 0666);
   int count = 0;
   int fd = open (FIFO_FILE, O_WRONLY);
   
   while (count < 5 )
   {
      write (fd, "hello", 5);
      printf ("Sent string is hello\n");
      /* This sleep makes sure that by the second write,
       * pipe at the server end is closed and hence we see SIGPIPE*/
      sleep (10);
      count++;
   }  
   
   close (fd);
   return 0;
}  

server.c

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define FIFO_FILE "MYFIFO"
int main()
{
   char readbuf[80];
   int fd = open(FIFO_FILE, O_RDONLY);
   int read_bytes = read (fd, readbuf, sizeof(readbuf));
   readbuf[read_bytes] = '\0';
   printf("Received string: \"%s\n", readbuf);

   close (fd);
   return 0;
}

Output:
server side

[aprakash@wtl-lview-6 named_pipe]$ gcc server.c -o ser
[aprakash@wtl-lview-6 named_pipe]$ ./ser 
Received string: "hello
[aprakash@wtl-lview-6 named_pipe]$ 

client side

[aprakash@wtl-lview-6 named_pipe]$ gcc client.c  -o cli
[aprakash@wtl-lview-6 named_pipe]$ ./cli 
Sent string is hello

 Waiting for server to close pipe at its end
[aprakash@wtl-lview-6 named_pipe]$ 

Output on client side once SIGPIPE is ignored(signal(SIGPIPE, SIG_IGN);

[aprakash@wtl-lview-6 named_pipe]$ gcc client.c  -o cli
[aprakash@wtl-lview-6 named_pipe]$ ./cli 
 Sent string is hello

 Waiting for server to close pipe at its end
 Sent string is hello

 Waiting for server to close pipe at its end
 Sent string is hello

 Waiting for server to close pipe at its end
 Sent string is hello

 Waiting for server to close pipe at its end
 Sent string is hello

 Waiting for server to close pipe at its end
[aprakash@wtl-lview-6 named_pipe]$ 


Categories: Operating system (OS)

1 reply

Trackbacks

  1. Un-named Pipes - Tech Access

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: