Under what conditions exactly does SIGPIPE happen?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
2
down vote

favorite
1












Say we have a named pipe called fifo, and we're reading and writing to it from two different shells. Consider these two examples:



shell 1$ echo foo > fifo
<hangs>
shell 2$ cat fifo
foo
shell 1$ echo bar > fifo
<hangs>



shell 1$ cat > fifo
<typing> foo
<hangs>
shell 2$ cat fifo
foo
^C
shell 1$
<typing> bar
<exits>


I can't wrap my head around what happens in these examples, and in particular why trying to write 'bar' to the pipe in the first example results in a blocking call, whereas in the second example it triggers a SIGPIPE.



I do understand that in the first case, two separate processes write to the pipe, and thus it is opened twice, while in the second case it is only opened once by a single process and written to twice, with the process reading from the pipe being killed in the meantime. What I don't understand is how that affects the behaviour of write.



The pipe(7) man page states:




If all file descriptors referring to the read end of a pipe have been closed, then a write(2) will cause a SIGPIPE signal to be generated for the calling process.




This condition doesn't sound clear to me. A closed file descriptor just ceases to be a file descriptor, right? How does saying "the reading end of the pipe has been closed" differ from "the reading end of the pipe is not open"?



I hope my question was clear enough. By the way, if you could suggest pointers for understanding in details the functioning of Unix pipes in relationship to open, close, read and write operations, I'd greatly appreciate it.







share|improve this question
























    up vote
    2
    down vote

    favorite
    1












    Say we have a named pipe called fifo, and we're reading and writing to it from two different shells. Consider these two examples:



    shell 1$ echo foo > fifo
    <hangs>
    shell 2$ cat fifo
    foo
    shell 1$ echo bar > fifo
    <hangs>



    shell 1$ cat > fifo
    <typing> foo
    <hangs>
    shell 2$ cat fifo
    foo
    ^C
    shell 1$
    <typing> bar
    <exits>


    I can't wrap my head around what happens in these examples, and in particular why trying to write 'bar' to the pipe in the first example results in a blocking call, whereas in the second example it triggers a SIGPIPE.



    I do understand that in the first case, two separate processes write to the pipe, and thus it is opened twice, while in the second case it is only opened once by a single process and written to twice, with the process reading from the pipe being killed in the meantime. What I don't understand is how that affects the behaviour of write.



    The pipe(7) man page states:




    If all file descriptors referring to the read end of a pipe have been closed, then a write(2) will cause a SIGPIPE signal to be generated for the calling process.




    This condition doesn't sound clear to me. A closed file descriptor just ceases to be a file descriptor, right? How does saying "the reading end of the pipe has been closed" differ from "the reading end of the pipe is not open"?



    I hope my question was clear enough. By the way, if you could suggest pointers for understanding in details the functioning of Unix pipes in relationship to open, close, read and write operations, I'd greatly appreciate it.







    share|improve this question






















      up vote
      2
      down vote

      favorite
      1









      up vote
      2
      down vote

      favorite
      1






      1





      Say we have a named pipe called fifo, and we're reading and writing to it from two different shells. Consider these two examples:



      shell 1$ echo foo > fifo
      <hangs>
      shell 2$ cat fifo
      foo
      shell 1$ echo bar > fifo
      <hangs>



      shell 1$ cat > fifo
      <typing> foo
      <hangs>
      shell 2$ cat fifo
      foo
      ^C
      shell 1$
      <typing> bar
      <exits>


      I can't wrap my head around what happens in these examples, and in particular why trying to write 'bar' to the pipe in the first example results in a blocking call, whereas in the second example it triggers a SIGPIPE.



      I do understand that in the first case, two separate processes write to the pipe, and thus it is opened twice, while in the second case it is only opened once by a single process and written to twice, with the process reading from the pipe being killed in the meantime. What I don't understand is how that affects the behaviour of write.



      The pipe(7) man page states:




      If all file descriptors referring to the read end of a pipe have been closed, then a write(2) will cause a SIGPIPE signal to be generated for the calling process.




      This condition doesn't sound clear to me. A closed file descriptor just ceases to be a file descriptor, right? How does saying "the reading end of the pipe has been closed" differ from "the reading end of the pipe is not open"?



      I hope my question was clear enough. By the way, if you could suggest pointers for understanding in details the functioning of Unix pipes in relationship to open, close, read and write operations, I'd greatly appreciate it.







      share|improve this question












      Say we have a named pipe called fifo, and we're reading and writing to it from two different shells. Consider these two examples:



      shell 1$ echo foo > fifo
      <hangs>
      shell 2$ cat fifo
      foo
      shell 1$ echo bar > fifo
      <hangs>



      shell 1$ cat > fifo
      <typing> foo
      <hangs>
      shell 2$ cat fifo
      foo
      ^C
      shell 1$
      <typing> bar
      <exits>


      I can't wrap my head around what happens in these examples, and in particular why trying to write 'bar' to the pipe in the first example results in a blocking call, whereas in the second example it triggers a SIGPIPE.



      I do understand that in the first case, two separate processes write to the pipe, and thus it is opened twice, while in the second case it is only opened once by a single process and written to twice, with the process reading from the pipe being killed in the meantime. What I don't understand is how that affects the behaviour of write.



      The pipe(7) man page states:




      If all file descriptors referring to the read end of a pipe have been closed, then a write(2) will cause a SIGPIPE signal to be generated for the calling process.




      This condition doesn't sound clear to me. A closed file descriptor just ceases to be a file descriptor, right? How does saying "the reading end of the pipe has been closed" differ from "the reading end of the pipe is not open"?



      I hope my question was clear enough. By the way, if you could suggest pointers for understanding in details the functioning of Unix pipes in relationship to open, close, read and write operations, I'd greatly appreciate it.









      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 24 at 23:53









      Naïm Favier

      235




      235




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          5
          down vote



          accepted










          Your example is using a fifo not a pipe, so is subject to fifo(7). pipe(7) also tells:




          A FIFO (short for First In First Out) has a name within the
          filesystem (created using mkfifo(3)), and is opened using open(2).
          Any process may open a FIFO, assuming the file permissions allow it.
          The read end is opened using the O_RDONLY flag; the write end is
          opened using the O_WRONLY flag. See fifo(7) for further details.
          Note: although FIFOs have a pathname in the filesystem, I/O on FIFOs
          does not involve operations on the underlying device (if there is
          one).



          I/O on pipes and FIFOs

          The only difference between pipes and FIFOs is the manner in which
          they are created and opened. Once these tasks have been
          accomplished, I/O on pipes and FIFOs has exactly the same semantics.




          So now from fifo(7):




          The kernel maintains exactly one pipe object for each FIFO special
          file that is opened by at least one process. The FIFO must be opened
          on both ends (reading and writing) before data can be passed.
          Normally, opening the FIFO blocks until the other end is opened also.




          So before both ends (here meaning there is at least a reader and a writer) are opened, write blocks as per fifo(7). After both ends have been opened, and then (the) reading end(s) closed, write generates SIGPIPE as per pipe(7).



          For an example of pipe usage (not fifo) look at the example section of pipe(2) : involves pipe() (no open(), since pipe() actually created the pipe pair opened), close(), read() write() and fork() (there's almost always a fork() around when using a pipe).



          The simpliest way to handle SIGPIPE from your own C code if you don't want it to die when writing to a fifo, would be to call signal(SIGPIPE, SIG_IGN); and handle it by checking for errno EPIPE after each write() instead.






          share|improve this answer





























            up vote
            0
            down vote













            Writing to a pipe or FIFO that doesn't have a reading process is treated as an error condition; it generates a SIGPIPE signal, and fails with error code EPIPE if the signal is handled or blocked.






            share|improve this answer




















              Your Answer







              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "106"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              convertImagesToLinks: false,
              noModals: false,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );








               

              draft saved


              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f433345%2funder-what-conditions-exactly-does-sigpipe-happen%23new-answer', 'question_page');

              );

              Post as a guest






























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              5
              down vote



              accepted










              Your example is using a fifo not a pipe, so is subject to fifo(7). pipe(7) also tells:




              A FIFO (short for First In First Out) has a name within the
              filesystem (created using mkfifo(3)), and is opened using open(2).
              Any process may open a FIFO, assuming the file permissions allow it.
              The read end is opened using the O_RDONLY flag; the write end is
              opened using the O_WRONLY flag. See fifo(7) for further details.
              Note: although FIFOs have a pathname in the filesystem, I/O on FIFOs
              does not involve operations on the underlying device (if there is
              one).



              I/O on pipes and FIFOs

              The only difference between pipes and FIFOs is the manner in which
              they are created and opened. Once these tasks have been
              accomplished, I/O on pipes and FIFOs has exactly the same semantics.




              So now from fifo(7):




              The kernel maintains exactly one pipe object for each FIFO special
              file that is opened by at least one process. The FIFO must be opened
              on both ends (reading and writing) before data can be passed.
              Normally, opening the FIFO blocks until the other end is opened also.




              So before both ends (here meaning there is at least a reader and a writer) are opened, write blocks as per fifo(7). After both ends have been opened, and then (the) reading end(s) closed, write generates SIGPIPE as per pipe(7).



              For an example of pipe usage (not fifo) look at the example section of pipe(2) : involves pipe() (no open(), since pipe() actually created the pipe pair opened), close(), read() write() and fork() (there's almost always a fork() around when using a pipe).



              The simpliest way to handle SIGPIPE from your own C code if you don't want it to die when writing to a fifo, would be to call signal(SIGPIPE, SIG_IGN); and handle it by checking for errno EPIPE after each write() instead.






              share|improve this answer


























                up vote
                5
                down vote



                accepted










                Your example is using a fifo not a pipe, so is subject to fifo(7). pipe(7) also tells:




                A FIFO (short for First In First Out) has a name within the
                filesystem (created using mkfifo(3)), and is opened using open(2).
                Any process may open a FIFO, assuming the file permissions allow it.
                The read end is opened using the O_RDONLY flag; the write end is
                opened using the O_WRONLY flag. See fifo(7) for further details.
                Note: although FIFOs have a pathname in the filesystem, I/O on FIFOs
                does not involve operations on the underlying device (if there is
                one).



                I/O on pipes and FIFOs

                The only difference between pipes and FIFOs is the manner in which
                they are created and opened. Once these tasks have been
                accomplished, I/O on pipes and FIFOs has exactly the same semantics.




                So now from fifo(7):




                The kernel maintains exactly one pipe object for each FIFO special
                file that is opened by at least one process. The FIFO must be opened
                on both ends (reading and writing) before data can be passed.
                Normally, opening the FIFO blocks until the other end is opened also.




                So before both ends (here meaning there is at least a reader and a writer) are opened, write blocks as per fifo(7). After both ends have been opened, and then (the) reading end(s) closed, write generates SIGPIPE as per pipe(7).



                For an example of pipe usage (not fifo) look at the example section of pipe(2) : involves pipe() (no open(), since pipe() actually created the pipe pair opened), close(), read() write() and fork() (there's almost always a fork() around when using a pipe).



                The simpliest way to handle SIGPIPE from your own C code if you don't want it to die when writing to a fifo, would be to call signal(SIGPIPE, SIG_IGN); and handle it by checking for errno EPIPE after each write() instead.






                share|improve this answer
























                  up vote
                  5
                  down vote



                  accepted







                  up vote
                  5
                  down vote



                  accepted






                  Your example is using a fifo not a pipe, so is subject to fifo(7). pipe(7) also tells:




                  A FIFO (short for First In First Out) has a name within the
                  filesystem (created using mkfifo(3)), and is opened using open(2).
                  Any process may open a FIFO, assuming the file permissions allow it.
                  The read end is opened using the O_RDONLY flag; the write end is
                  opened using the O_WRONLY flag. See fifo(7) for further details.
                  Note: although FIFOs have a pathname in the filesystem, I/O on FIFOs
                  does not involve operations on the underlying device (if there is
                  one).



                  I/O on pipes and FIFOs

                  The only difference between pipes and FIFOs is the manner in which
                  they are created and opened. Once these tasks have been
                  accomplished, I/O on pipes and FIFOs has exactly the same semantics.




                  So now from fifo(7):




                  The kernel maintains exactly one pipe object for each FIFO special
                  file that is opened by at least one process. The FIFO must be opened
                  on both ends (reading and writing) before data can be passed.
                  Normally, opening the FIFO blocks until the other end is opened also.




                  So before both ends (here meaning there is at least a reader and a writer) are opened, write blocks as per fifo(7). After both ends have been opened, and then (the) reading end(s) closed, write generates SIGPIPE as per pipe(7).



                  For an example of pipe usage (not fifo) look at the example section of pipe(2) : involves pipe() (no open(), since pipe() actually created the pipe pair opened), close(), read() write() and fork() (there's almost always a fork() around when using a pipe).



                  The simpliest way to handle SIGPIPE from your own C code if you don't want it to die when writing to a fifo, would be to call signal(SIGPIPE, SIG_IGN); and handle it by checking for errno EPIPE after each write() instead.






                  share|improve this answer














                  Your example is using a fifo not a pipe, so is subject to fifo(7). pipe(7) also tells:




                  A FIFO (short for First In First Out) has a name within the
                  filesystem (created using mkfifo(3)), and is opened using open(2).
                  Any process may open a FIFO, assuming the file permissions allow it.
                  The read end is opened using the O_RDONLY flag; the write end is
                  opened using the O_WRONLY flag. See fifo(7) for further details.
                  Note: although FIFOs have a pathname in the filesystem, I/O on FIFOs
                  does not involve operations on the underlying device (if there is
                  one).



                  I/O on pipes and FIFOs

                  The only difference between pipes and FIFOs is the manner in which
                  they are created and opened. Once these tasks have been
                  accomplished, I/O on pipes and FIFOs has exactly the same semantics.




                  So now from fifo(7):




                  The kernel maintains exactly one pipe object for each FIFO special
                  file that is opened by at least one process. The FIFO must be opened
                  on both ends (reading and writing) before data can be passed.
                  Normally, opening the FIFO blocks until the other end is opened also.




                  So before both ends (here meaning there is at least a reader and a writer) are opened, write blocks as per fifo(7). After both ends have been opened, and then (the) reading end(s) closed, write generates SIGPIPE as per pipe(7).



                  For an example of pipe usage (not fifo) look at the example section of pipe(2) : involves pipe() (no open(), since pipe() actually created the pipe pair opened), close(), read() write() and fork() (there's almost always a fork() around when using a pipe).



                  The simpliest way to handle SIGPIPE from your own C code if you don't want it to die when writing to a fifo, would be to call signal(SIGPIPE, SIG_IGN); and handle it by checking for errno EPIPE after each write() instead.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Mar 25 at 1:55

























                  answered Mar 25 at 0:51









                  A.B

                  2,5651315




                  2,5651315






















                      up vote
                      0
                      down vote













                      Writing to a pipe or FIFO that doesn't have a reading process is treated as an error condition; it generates a SIGPIPE signal, and fails with error code EPIPE if the signal is handled or blocked.






                      share|improve this answer
























                        up vote
                        0
                        down vote













                        Writing to a pipe or FIFO that doesn't have a reading process is treated as an error condition; it generates a SIGPIPE signal, and fails with error code EPIPE if the signal is handled or blocked.






                        share|improve this answer






















                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          Writing to a pipe or FIFO that doesn't have a reading process is treated as an error condition; it generates a SIGPIPE signal, and fails with error code EPIPE if the signal is handled or blocked.






                          share|improve this answer












                          Writing to a pipe or FIFO that doesn't have a reading process is treated as an error condition; it generates a SIGPIPE signal, and fails with error code EPIPE if the signal is handled or blocked.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Mar 25 at 11:02









                          Mumtaz Ahmad

                          62




                          62






















                               

                              draft saved


                              draft discarded


























                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f433345%2funder-what-conditions-exactly-does-sigpipe-happen%23new-answer', 'question_page');

                              );

                              Post as a guest













































































                              Popular posts from this blog

                              Peggy Mitchell

                              Palaiologos

                              The Forum (Inglewood, California)