Why does SIGPIPE exist?

后端 未结 5 993
梦如初夏
梦如初夏 2020-11-30 20:04

From my understanding, SIGPIPE can only occur as the result of a write(), which can (and does) return -1 and set errno to EPIPE<

5条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-30 20:44

    Machine info:

    Linux 3.2.0-53-generic #81-Ubuntu SMP Thu Aug 22 21:01:03 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

    gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

    I wrote this code below:

    // Writes characters to stdout in an infinite loop, also counts 
    // the number of characters generated and prints them in sighandler
    // writestdout.c
    
    # include 
    # include 
    # include 
    # include 
    
    int writeCount = 0;    
    void sighandler(int sig) {
        char buf1[30] ;
        sprintf(buf1,"signal %d writeCount %d\n", sig, writeCount);
        ssize_t leng = strlen(buf1);
        write(2, buf1, leng);
        _exit(1);
    
    }
    
    int main() {
    
        int i = 0;
        char buf[2] = "a";
    
        struct sigaction ss;
        ss.sa_handler = sighandler;
    
        sigaction(13, &ss, NULL);
    
        while(1) {
    
            /* if (writeCount == 4) {
    
                write(2, "4th char\n", 10);
    
            } */
    
            ssize_t c = write(1, buf, 1);
            writeCount++;
    
        }
    
    }
    

    // Reads only 3 characters from stdin and exits
    // readstdin.c
    
    # include 
    # include 
    
    int main() {
    
        ssize_t n ;        
        char a[5];        
        n = read(0, a, 3);
        printf("read %zd bytes\n", n);
        return(0);
    
    }
    

    Output:

    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 11486
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 429
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 281
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 490
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 433
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 318
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 468
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 11866
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 496
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 284
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 271
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 416
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 11268
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 427
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 8812
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 394
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 10937
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 10931
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 3554
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 499
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 283
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 11133
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 451
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 493
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 233
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 11397
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 492
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 547
    
    $ ./writestdout | ./readstdin 
    read 3 bytes
    signal 13 writeCount 441
    

    You can see that in every instance SIGPIPE is only received after more than 3 characters are (tried to be) written by the writing process.

    Does this not prove that SIGPIPE is not generated immediately after reading process terminates but after an attempt to write some more data to a closed pipe?

提交回复
热议问题