pselect returns early? - Unix

This is a discussion on pselect returns early? - Unix ; Hi, is it the expected behavior that pselect returns at once when a child process is running? Could this be a bug? thomas@azalin:~/test$ uname -a SunOS azalin 5.10 Generic_137111-04 sun4u sparc SUNW,Sun-Blade-2500 thomas@azalin:~/test$ cat p3.c #include #include #include #include #include ...

+ Reply to Thread
Page 1 of 2 1 2 LastLast
Results 1 to 20 of 25

Thread: pselect returns early?

  1. pselect returns early?

    Hi,

    is it the expected behavior that pselect returns at once when a child
    process is running? Could this be a bug?

    thomas@azalin:~/test$ uname -a
    SunOS azalin 5.10 Generic_137111-04 sun4u sparc SUNW,Sun-Blade-2500
    thomas@azalin:~/test$ cat p3.c
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    int main(void)
    {
    char buf[4096];
    int fd, n;
    pthread_t thr;
    pthread_attr_t attr;
    fd_set readfds, errorfds;

    fd = open("fifo",O_RDONLY|O_NONBLOCK);
    n = fcntl(fd,F_GETFL);
    printf("n = %x\n",n);
    n &= ~O_NONBLOCK;
    printf("n = %x\n",n);
    fcntl(fd,F_SETFL,n);
    n = fcntl(fd,F_GETFL);
    printf("n = %x\n",n);
    FD_ZERO(&readfds);
    FD_SET(fd,&readfds);
    FD_ZERO(&errorfds);
    FD_SET(fd,&errorfds);
    if (0 == fork()) {
    while (1) {
    sleep(1000);
    }
    }
    while (1) {
    int ret;
    //waitpid(0,&ret,WNOHANG);
    n = pselect(fd+1,&readfds,0,&errorfds,0,0);
    printf("pselect = %d\n",n);
    n = read(fd,buf,sizeof(buf));
    if (n == 0) {
    close(fd);
    fd = open("fifo",O_RDONLY|O_NONBLOCK);
    n = fcntl(fd,F_GETFL);
    n &= ~O_NONBLOCK;
    //printf("fcntl = %x\n",n);
    fcntl(fd,F_SETFL,n);
    } else {
    write(STDOUT_FILENO,buf,n);
    }
    }
    close(fd);
    return 0;
    }
    thomas@azalin:~/test$ mkfifo fifo
    thomas@azalin:~/test$ cc -g p3.c
    "p3.c", line 52: warning: statement not reached

    First pselect hangs. Then run 'echo something >> fifo'. On Solaris,
    using truss, I see the following sequence spinning:
    pollsys(0xFFBFD9B0, 1, 0x00000000, 0x00000000) = 1
    pselect = 1
    write(1, " p s e l e c t = 1\n", 12) = 12
    read(3, 0xFFBFDB54, 4096) = 0
    close(3) = 0
    open("fifo", O_RDONLY|O_NONBLOCK) = 3
    fcntl(3, F_GETFL) = 128
    fcntl(3, F_SETFL, (no flags)) = 0
    pollsys(0xFFBFD9B0, 1, 0x00000000, 0x00000000) = 1
    pselect = 1
    write(1, " p s e l e c t = 1\n", 12) = 12
    read(3, 0xFFBFDB54, 4096) = 0
    close(3) = 0
    open("fifo", O_RDONLY|O_NONBLOCK) = 3
    fcntl(3, F_GETFL) = 128
    fcntl(3, F_SETFL, (no flags)) = 0

    Linux blocks as expected.

    If I remove the "if (0 == fork())..." part, pselect blocks as expected
    in pollsys.

    - Thomas

  2. Re: pselect returns early?

    On Aug 12, 7:41 pm, Thomas Maier-Komor
    wrote:
    > Hi,
    >
    > is it the expected behavior that pselect returns at once when a child
    > process is running? Could this be a bug?


    It's hard to tell; I don't have a Solaris 10 machine to test this.
    However, I note that your code doesn't have any error checking. It
    could be that one of the system calls is failing for some reason. Try
    checking the return values of all your system calls, and post here to
    say what you find.

  3. Re: pselect returns early?

    fjblurt@yahoo.com wrote:
    > On Aug 12, 7:41 pm, Thomas Maier-Komor
    > wrote:
    >> Hi,
    >>
    >> is it the expected behavior that pselect returns at once when a child
    >> process is running? Could this be a bug?

    >
    > It's hard to tell; I don't have a Solaris 10 machine to test this.
    > However, I note that your code doesn't have any error checking. It
    > could be that one of the system calls is failing for some reason. Try
    > checking the return values of all your system calls, and post here to
    > say what you find.


    OK, 4am is a little bit early, to produce something bug free. There was
    a minor issue, but the problem remains.

    I didn't reinitialize the arguments for pselect, which had of course
    only minor effect in this specific situation. Here is the changed code
    and the output of truss:



    There is no error checking because I run this program using truss/strace
    - here's the output of truss on Solaris, as you can see there are no errors:

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    int main(void)
    {
    char buf[4096];
    int fd, n;

    fd = open("fifo",O_RDONLY|O_NONBLOCK);
    n = fcntl(fd,F_GETFL);
    printf("n = %x\n",n);
    n &= ~O_NONBLOCK;
    printf("n = %x\n",n);
    fcntl(fd,F_SETFL,n);
    n = fcntl(fd,F_GETFL);
    printf("n = %x\n",n);
    if (0 == fork()) {
    while (1) {
    sleep(1000);
    }
    }
    while (1) {
    int ret;
    fd_set readfds, errorfds;
    FD_ZERO(&readfds);
    FD_SET(fd,&readfds);
    FD_ZERO(&errorfds);
    FD_SET(fd,&errorfds);
    n = pselect(fd+1,&readfds,0,&errorfds,0,0);
    printf("pselect = %d\n",n);
    n = read(fd,buf,sizeof(buf));
    if (n == 0) {
    close(fd);
    fd = open("fifo",O_RDONLY|O_NONBLOCK);
    n = fcntl(fd,F_GETFL);
    n &= ~O_NONBLOCK;
    fcntl(fd,F_SETFL,n);
    } else {
    write(STDOUT_FILENO,buf,n);
    }
    }
    close(fd);
    return 0;
    }

    this is the output of 'truss -u lib'. As you can see, all calls succeed
    as expected. I made some inline comments with #####.

    /1: open("fifo", O_RDONLY|O_NONBLOCK) = 3
    /1@1: <- libcpen() = 3
    ##### fifo opened successfully

    /1@1: -> libc:fcntl(0x3, 0x3, 0x0, 0x0)
    /1: fcntl(3, F_GETFL) = 128
    /1@1: <- libc:fcntl() = 128
    ##### got the fifo flags successfully

    /1@1: -> libcrintf(0x11110, 0x80, 0x0, 0x0)
    /1: ioctl(1, TCGETA, 0xFFBFCBE4) = 0
    /1: fstat64(1, 0xFFBFCB00) = 0
    /1: write(1, " n = 8 0\n", 7) = 7
    /1@1: <- libcrintf() = 7
    ##### printf'ed flags

    /1@1: -> libcrintf(0x11118, 0x0, 0x0, 0xff373342)
    /1: write(1, " n = 0\n", 6) = 6
    /1@1: <- libcrintf() = 6
    ##### printf'ed flags after masking out O_NONBLOCK

    /1@1: -> libc:fcntl(0x3, 0x4, 0x0, 0xff373342)
    /1: fcntl(3, F_SETFL, (no flags)) = 0
    /1@1: <- libc:fcntl() = 0
    ##### flags set successfully

    /1@1: -> libc:fcntl(0x3, 0x3, 0x0, 0xff373342)
    /1: fcntl(3, F_GETFL) = 0
    /1@1: <- libc:fcntl() = 0
    ##### flags returned one more time - O_NONBLOCK is no more set

    /1@1: -> libcrintf(0x11120, 0x0, 0x0, 0xff373342)
    /1: write(1, " n = 0\n", 6) = 6
    /1@1: <- libcrintf() = 6
    ##### printf'ed flags

    /1@1: -> libc:fork(0x6, 0xff373324, 0x0, 0xff373342)
    /1: schedctl() = 0xFF3E6000
    /1: fork1() = 1261
    /1: lwp_sigmask(SIG_SETMASK, 0x00000000, 0x00000000) = 0xFFBFFEFF
    [0x0000FFF
    F]
    /1@1: <- libc:fork() = 1261
    ##### successfully fork'ed

    /1: stat("/platform/SUNW,Sun-Blade-2500/lib/libc_psr.so.1",
    0xFFBFD398) = 0
    /1: resolvepath("/platform/SUNW,Sun-Blade-2500/lib/libc_psr.so.1",
    "/platfor
    m/sun4u-us3/lib/libc_psr.so.1", 1023) = 37
    /1: open("/platform/SUNW,Sun-Blade-2500/lib/libc_psr.so.1",
    O_RDONLY) = 4
    /1: mmap(0x00010000, 32768, PROT_READ|PROT_EXEC,
    MAP_PRIVATE|MAP_ALIGN, 4, 0
    ) = 0xFF3A0000
    /1: munmap(0xFF3A2000, 24576) = 0
    /1@1: -> libc:thr_self(0xff3f7f68, 0xff342fa8, 0xff3f4910, 0xff3bea6c)
    /1@1: <- libc:thr_self() = 1
    /1: mmap(0x00000000, 8192, PROT_READ|PROT_WRITE|PROT_EXEC,
    MAP_PRIVATE|MAP_A
    NON, -1, 0) = 0xFF3F0000
    /1: close(4) = 0
    ##### that's post fork stuff

    /1@1: -> libcselect(0x4, 0xffbfdac8, 0x0, 0xffbfda48)
    /1: pollsys(0xFFBFD9B8, 1, 0x00000000, 0x00000000) (sleeping...)
    ##### pselect sleeps the first time as expected

    /1: pollsys(0xFFBFD9B8, 1, 0x00000000, 0x00000000) = 1
    /1@1: <- libcselect() = 1
    ##### and returns 1 as expected

    /1@1: -> libcrintf(0x11128, 0x1, 0xffbfda48, 0x1)
    /1: write(1, " p s e l e c t = 1\n", 12) = 12
    /1@1: <- libcrintf() = 12
    ##### printf'ed pselect result

    /1@1: -> libc:read(0x3, 0xffbfdb54, 0x1000, 0xff373342)
    /1: read(3, " a . o u t *\n c o r e\n".., 4096) = 144
    /1@1: <- libc:read() = 144
    ##### read garbage from fifo successfully

    /1@1: -> libc:write(0x1, 0xffbfdb54, 0x90, 0x0)
    /1: write(1, " a . o u t *\n c o r e\n".., 144) = 144
    /1@1: <- libc:write() = 144
    ##### wrote garbage succesffully to stdout

    /1@1: -> libcselect(0x4, 0xffbfdac8, 0x0, 0xffbfda48)
    /1: pollsys(0xFFBFD9B8, 1, 0x00000000, 0x00000000) = 1
    /1@1: <- libcselect() = 2
    ######
    ###### NOW WHAT DO WE HAVE HERE?
    ###### pselect returns 2, instead of blocking
    ######

    /1@1: -> libcrintf(0x11128, 0x2, 0xffbfda48, 0x2)
    /1: write(1, " p s e l e c t = 2\n", 12) = 12
    /1@1: <- libcrintf() = 12
    /1@1: -> libc:read(0x3, 0xffbfdb54, 0x1000, 0xff373342)
    /1: read(3, 0xFFBFDB54, 4096) = 0
    /1@1: <- libc:read() = 0
    ###### reading the fifo returns 0 as there is no data on the FIFO

    /1@1: -> libc:close(0x3, 0xffbfdb54, 0x0, 0x0)
    /1: close(3) = 0
    ###### successful close

    /1@1: <- libc:close() = 0
    /1@1: -> libcpen(0x11138, 0x80, 0xff392a00, 0x0)
    /1: open("fifo", O_RDONLY|O_NONBLOCK) = 3
    /1@1: <- libcpen() = 3
    ###### reopened the fifo

    /1@1: -> libc:fcntl(0x3, 0x3, 0x0, 0x0)
    /1: fcntl(3, F_GETFL) = 128
    /1@1: <- libc:fcntl() = 128
    /1@1: -> libc:fcntl(0x3, 0x4, 0x0, 0x0)
    /1: fcntl(3, F_SETFL, (no flags)) = 0
    /1@1: <- libc:fcntl() = 0
    ##### flags reset as before

    /1@1: -> libcselect(0x4, 0xffbfdac8, 0x0, 0xffbfda48)
    /1: pollsys(0xFFBFD9B8, 1, 0x00000000, 0x00000000) = 1
    /1@1: <- libcselect() = 2
    ##### AND ON IT GOES....

    /1@1: -> libcrintf(0x11128, 0x2, 0xffbfda48, 0x2)
    /1: write(1, " p s e l e c t = 2\n", 12) = 12
    /1@1: <- libcrintf() = 12
    /1@1: -> libc:read(0x3, 0xffbfdb54, 0x1000, 0xff373342)
    /1: read(3, 0xFFBFDB54, 4096) = 0
    /1@1: <- libc:read() = 0
    /1@1: -> libc:close(0x3, 0xffbfdb54, 0x0, 0x0)
    /1: close(3) = 0
    /1@1: <- libc:close() = 0
    /1@1: -> libcpen(0x11138, 0x80, 0xff392a00, 0x0)
    /1: open("fifo", O_RDONLY|O_NONBLOCK) = 3
    /1@1: <- libcpen() = 3
    /1@1: -> libc:fcntl(0x3, 0x3, 0x0, 0x0)
    /1: fcntl(3, F_GETFL) = 128
    /1@1: <- libc:fcntl() = 128
    /1@1: -> libc:fcntl(0x3, 0x4, 0x0, 0x0)
    /1: fcntl(3, F_SETFL, (no flags)) = 0
    /1@1: <- libc:fcntl() = 0
    /1@1: -> libcselect(0x4, 0xffbfdac8, 0x0, 0xffbfda48)
    /1: pollsys(0xFFBFD9B8, 1, 0x00000000, 0x00000000) = 1
    /1@1: <- libcselect() = 2
    /1@1: -> libcrintf(0x11128, 0x2, 0xffbfda48, 0x2)
    /1: write(1, " p s e l e c t = 2\n", 12) = 12
    /1@1: <- libcrintf() = 12
    /1@1: -> libc:read(0x3, 0xffbfdb54, 0x1000, 0xff373342)
    /1: read(3, 0xFFBFDB54, 4096) = 0
    /1@1: <- libc:read() = 0
    /1@1: -> libc:close(0x3, 0xffbfdb54, 0x0, 0x0)
    /1: close(3) = 0
    /1@1: <- libc:close() = 0
    /1@1: -> libcpen(0x11138, 0x80, 0xff392a00, 0x0)
    /1: open("fifo", O_RDONLY|O_NONBLOCK) = 3

  4. Re: pselect returns early?

    Thomas Maier-Komor wrote:

    > while (1) {
    > int ret;
    > //waitpid(0,&ret,WNOHANG);
    > n = pselect(fd+1,&readfds,0,&errorfds,0,0);
    > printf("pselect = %d\n",n);
    > n = read(fd,buf,sizeof(buf));
    > if (n == 0) {
    > close(fd);
    > fd = open("fifo",O_RDONLY|O_NONBLOCK);
    > n = fcntl(fd,F_GETFL);
    > n &= ~O_NONBLOCK;
    > //printf("fcntl = %x\n",n);
    > fcntl(fd,F_SETFL,n);
    > } else {
    > write(STDOUT_FILENO,buf,n);
    > }
    > }
    > close(fd);
    > return 0;
    > }
    > thomas@azalin:~/test$ mkfifo fifo
    > thomas@azalin:~/test$ cc -g p3.c
    > "p3.c", line 52: warning: statement not reached


    > First pselect hangs. Then run 'echo something >> fifo'. On Solaris,
    > using truss, I see the following sequence spinning:
    > pollsys(0xFFBFD9B0, 1, 0x00000000, 0x00000000) = 1
    > pselect = 1
    > write(1, " p s e l e c t = 1\n", 12) = 12
    > read(3, 0xFFBFDB54, 4096) = 0


    This is odd. I wonder why read() isn't returning the echo'd string.

    > close(3) = 0
    > open("fifo", O_RDONLY|O_NONBLOCK) = 3
    > fcntl(3, F_GETFL) = 128
    > fcntl(3, F_SETFL, (no flags)) = 0
    > pollsys(0xFFBFD9B0, 1, 0x00000000, 0x00000000) = 1
    > pselect = 1
    > write(1, " p s e l e c t = 1\n", 12) = 12
    > read(3, 0xFFBFDB54, 4096) = 0
    > close(3) = 0
    > open("fifo", O_RDONLY|O_NONBLOCK) = 3
    > fcntl(3, F_GETFL) = 128
    > fcntl(3, F_SETFL, (no flags)) = 0
    >
    > Linux blocks as expected.


    Try not using errorfds. That's usually for sockets. Solaris may be trying to
    signal the exception that there are no readers. Just a working hypothesis.

    > If I remove the "if (0 == fork())..." part, pselect blocks as expected
    > in pollsys.


    Definitely odd.

    Also, try not changing the non-block flag. In other words, reduce the code
    to the simplest program which exhibits the behavior.

  5. Re: pselect returns early?

    Why do you clear the non blocking flag? Under what circumstances do
    you want your code to block?

    DS

  6. Re: pselect returns early?

    On Aug 12, 7:41*pm, Thomas Maier-Komor
    wrote:

    > is it the expected behavior that pselect returns at once when a child
    > process is running? Could this be a bug?


    The behavior of a FIFO opened for read with a non-blocking flag is
    undefined by POSIX. I'm not sure how Linux implements it, but I don't
    believe you can wait for nothing, which seems to be what you're trying
    to do.

    The child process has the FIFO opened, but cannot write to it (since
    it is opened in read-only). So there is nothing to wait for.

    DS

  7. Re: pselect returns early?

    Thomas Maier-Komor writes:

    [...]


    > while (1) {
    > int ret;
    > //waitpid(0,&ret,WNOHANG);
    > n = pselect(fd+1,&readfds,0,&errorfds,0,0);
    > printf("pselect = %d\n",n);
    > n = read(fd,buf,sizeof(buf));
    > if (n == 0) {
    > close(fd);
    > fd = open("fifo",O_RDONLY|O_NONBLOCK);
    > n = fcntl(fd,F_GETFL);
    > n &= ~O_NONBLOCK;
    > //printf("fcntl = %x\n",n);
    > fcntl(fd,F_SETFL,n);
    > } else {
    > write(STDOUT_FILENO,buf,n);
    > }
    > }
    > close(fd);
    > return 0;
    > }


    A general remark to this would be that you need to reinitialize the
    descriptor sets after (p)select has returned, because they are used to
    communicate which descriptors are ready.

  8. Re: pselect returns early?

    David Schwartz wrote:
    > On Aug 12, 7:41?pm, Thomas Maier-Komor
    > wrote:


    > > is it the expected behavior that pselect returns at once when a child
    > > process is running? Could this be a bug?


    > The behavior of a FIFO opened for read with a non-blocking flag is
    > undefined by POSIX. I'm not sure how Linux implements it, but I don't
    > believe you can wait for nothing, which seems to be what you're trying
    > to do.


    This doesn't sound right, w/o prefacing "if no other process has it open for
    writing". The language of read() and select() seems to cover all the bases:

    When attempting to read from an empty pipe or FIFO:

    * If no process has the pipe open for writing, read() shall return 0
    to indicate end-of-file.

    * If some process has the pipe open for writing and O_NONBLOCK is
    set, read() shall return -1 and set errno to [EAGAIN].

    * If some process has the pipe open for writing and O_NONBLOCK is clear,
    read() shall block the calling thread until some data is written or the pipe
    is closed by all processes that had the pipe open for writing.

    AND

    A descriptor shall be considered ready for reading when a call to an
    input function with O_NONBLOCK clear would not block, whether or not
    the function would transfer data successfully. (The function might
    return data, an end-of-file indication, or an error other than one
    indicating that it is blocked, and in each of these cases the
    descriptor shall be considered ready for reading.)

    > The child process has the FIFO opened, but cannot write to it (since
    > it is opened in read-only). So there is nothing to wait for.


    Perhaps if the OP also opened the fifo with O_WRONLY after opening with
    O_RDONLY. That shouldn't interfere w/ any other writing application, and the
    EOF indications should stop.


  9. Re: pselect returns early?

    Rainer Weikusat wrote:
    > Thomas Maier-Komor writes:
    >
    > [...]
    >
    >
    >> while (1) {
    >> int ret;
    >> //waitpid(0,&ret,WNOHANG);
    >> n = pselect(fd+1,&readfds,0,&errorfds,0,0);
    >> printf("pselect = %d\n",n);
    >> n = read(fd,buf,sizeof(buf));
    >> if (n == 0) {
    >> close(fd);
    >> fd = open("fifo",O_RDONLY|O_NONBLOCK);
    >> n = fcntl(fd,F_GETFL);
    >> n &= ~O_NONBLOCK;
    >> //printf("fcntl = %x\n",n);
    >> fcntl(fd,F_SETFL,n);
    >> } else {
    >> write(STDOUT_FILENO,buf,n);
    >> }
    >> }
    >> close(fd);
    >> return 0;
    >> }

    >
    > A general remark to this would be that you need to reinitialize the
    > descriptor sets after (p)select has returned, because they are used to
    > communicate which descriptors are ready.


    Yes, you are right. I've seen this after posting this message. Adjusting
    the code accordingly, didn't modify the outcome. So the problem is
    independent of this.

  10. Re: pselect returns early?

    William Ahern wrote:
    >
    > Definitely odd.
    >
    > Also, try not changing the non-block flag. In other words, reduce the code
    > to the simplest program which exhibits the behavior.


    replacing &errorfds with 0 in pselect doesn't change anything.

    Changing the open mode from non-blocking to blocking indeed fixes the
    problem. But I did know this already. The problem is that I must open
    the fifo non-blocking, because otherwise the open might block for a very
    long time and in consequence some other processing won't make any
    progress any more.

    So I really need to open non-blocking.

  11. Re: pselect returns early?

    David Schwartz wrote:
    > Why do you clear the non blocking flag? Under what circumstances do
    > you want your code to block?
    >
    > DS


    removing non-blocking. Fixes the issue. But I have to open it
    non-blocking. The alternative would be to create a separate thread for
    the fifo, and that is a substantial change I rather would like to avoid...

  12. Re: pselect returns early?

    William Ahern wrote:
    >
    > Perhaps if the OP also opened the fifo with O_WRONLY after opening with
    > O_RDONLY. That shouldn't interfere w/ any other writing application, and the
    > EOF indications should stop.
    >


    Are you sure about this? I could imagine that might screw up something
    else...

  13. Re: pselect returns early?

    On 13 Aug, 03:41, Thomas Maier-Komor
    wrote:
    >
    > is it the expected behavior that pselect returns at once when a child
    > process is running? Could this be a bug?



    Does the problem persist if the child closes its open file
    descriptors?


  14. Re: pselect returns early?

    Thomas Maier-Komor writes:
    > William Ahern wrote:
    >>
    >> Perhaps if the OP also opened the fifo with O_WRONLY after opening with
    >> O_RDONLY. That shouldn't interfere w/ any other writing application, and the
    >> EOF indications should stop.
    >>

    >
    > Are you sure about this? I could imagine that might screw up something
    > else...


    It will screw up something else, namely, that no EOF-indication will
    ever be received on this FIFO for as long as the writeable descriptor
    is open. But if this isn't a problem, the suggestion above appears (to
    me) to be a really good idea.

  15. Re: pselect returns early?

    William Pursell wrote:
    > On 13 Aug, 03:41, Thomas Maier-Komor
    > wrote:
    >> is it the expected behavior that pselect returns at once when a child
    >> process is running? Could this be a bug?

    >
    >
    > Does the problem persist if the child closes its open file
    > descriptors?
    >


    The exec occurs before the pipe gets opened. I tried it anyway, but, no,
    fcntl(fd,F_SETFD,FD_CLOEXEC) doesn't change anything.

  16. Re: pselect returns early?

    Rainer Weikusat wrote:
    > Thomas Maier-Komor writes:
    >> William Ahern wrote:
    >>> Perhaps if the OP also opened the fifo with O_WRONLY after opening with
    >>> O_RDONLY. That shouldn't interfere w/ any other writing application, and the
    >>> EOF indications should stop.
    >>>

    >> Are you sure about this? I could imagine that might screw up something
    >> else...

    >
    > It will screw up something else, namely, that no EOF-indication will
    > ever be received on this FIFO for as long as the writeable descriptor
    > is open. But if this isn't a problem, the suggestion above appears (to
    > me) to be a really good idea.


    This side effect is even positive, as it apparently makes reopening the
    pipe unnecessary.

    Seems like a really good workaround and a better solution as a whole for
    the application.

    Thanks,
    Thomas

  17. Re: pselect returns early?

    On Aug 13, 5:03 am, Thomas Maier-Komor
    wrote:

    > /1@1: -> libcrintf(0x11128, 0x2, 0xffbfda48, 0x2)
    > /1: write(1, " p s e l e c t = 2\n", 12) = 12
    > /1@1: <- libcrintf() = 12
    > /1@1: -> libc:read(0x3, 0xffbfdb54, 0x1000, 0xff373342)
    > /1: read(3, 0xFFBFDB54, 4096) = 0
    > /1@1: <- libc:read() = 0
    > ###### reading the fifo returns 0 as there is no data on the FIFO


    'read' *only* returns 0 for a pipe if all writing descriptors have
    been closed and the buffer is clear; this means that no data will ever
    be available again on the descriptor. If there's no data and *there
    still can be* and it's non-blocking then it returns -1.
    Kevin P. Barry

  18. Re: pselect returns early?

    ta0kira@yahoo.com wrote:
    > On Aug 13, 5:03 am, Thomas Maier-Komor
    > wrote:


    > > /1@1: -> libcrintf(0x11128, 0x2, 0xffbfda48, 0x2)
    > > /1: write(1, " p s e l e c t = 2\n", 12) = 12
    > > /1@1: <- libcrintf() = 12
    > > /1@1: -> libc:read(0x3, 0xffbfdb54, 0x1000, 0xff373342)
    > > /1: read(3, 0xFFBFDB54, 4096) = 0
    > > /1@1: <- libc:read() = 0
    > > ###### reading the fifo returns 0 as there is no data on the FIFO


    > 'read' *only* returns 0 for a pipe if all writing descriptors have
    > been closed and the buffer is clear; this means that no data will ever
    > be available again on the descriptor. If there's no data and *there
    > still can be* and it's non-blocking then it returns -1.
    > Kevin P. Barry


    That's not strictly true, is it? Another writer should be able to open the
    fifo for writing, and any data written should be readable through the
    original read descriptor. I'd _wager_ that Solaris has some sort of fcntl
    API that allows an app to clear the EOF indication, but that's just a guess.


  19. Re: pselect returns early?

    ta0kira@yahoo.com wrote:
    > On Aug 13, 5:03 am, Thomas Maier-Komor
    > wrote:
    >
    >> /1@1: -> libcrintf(0x11128, 0x2, 0xffbfda48, 0x2)
    >> /1: write(1, " p s e l e c t = 2\n", 12) = 12
    >> /1@1: <- libcrintf() = 12
    >> /1@1: -> libc:read(0x3, 0xffbfdb54, 0x1000, 0xff373342)
    >> /1: read(3, 0xFFBFDB54, 4096) = 0
    >> /1@1: <- libc:read() = 0
    >> ###### reading the fifo returns 0 as there is no data on the FIFO

    >
    > 'read' *only* returns 0 for a pipe if all writing descriptors have
    > been closed and the buffer is clear; this means that no data will ever
    > be available again on the descriptor. If there's no data and *there
    > still can be* and it's non-blocking then it returns -1.
    > Kevin P. Barry


    You are right, read only returns 0 if all writable file descriptors of
    the named pipe have been closed. That was the case in this situation.

    But the question was, why pselect returns 2, when it has been asked to
    wait for a readable file descriptor. Obviously, there is nothing to
    read. Additionally, this behavior only occurs, when a child process is
    running and once one kills the child process, pselect blocks again...

    Kind of weird isn't it?

    - Thomas

  20. Re: pselect returns early?

    Thomas Maier-Komor wrote:
    > ta0kira@yahoo.com wrote:
    >> On Aug 13, 5:03 am, Thomas Maier-Komor
    >> wrote:
    >>
    >>> /1@1: -> libcrintf(0x11128, 0x2, 0xffbfda48, 0x2)
    >>> /1: write(1, " p s e l e c t = 2\n", 12) = 12
    >>> /1@1: <- libcrintf() = 12
    >>> /1@1: -> libc:read(0x3, 0xffbfdb54, 0x1000, 0xff373342)
    >>> /1: read(3, 0xFFBFDB54, 4096) = 0
    >>> /1@1: <- libc:read() = 0
    >>> ###### reading the fifo returns 0 as there is no data on the FIFO

    >> 'read' *only* returns 0 for a pipe if all writing descriptors have
    >> been closed and the buffer is clear; this means that no data will ever
    >> be available again on the descriptor. If there's no data and *there
    >> still can be* and it's non-blocking then it returns -1.
    >> Kevin P. Barry

    >
    > You are right, read only returns 0 if all writable file descriptors of
    > the named pipe have been closed. That was the case in this situation.
    >
    > But the question was, why pselect returns 2, when it has been asked to
    > wait for a readable file descriptor. Obviously, there is nothing to
    > read. Additionally, this behavior only occurs, when a child process is
    > running and once one kills the child process, pselect blocks again...
    >
    > Kind of weird isn't it?
    >
    > - Thomas


    Hmm, again replying to myself...

    I just looked at it again and figured out that the source of the problem
    is the first file-descriptor still being open in the child process. I
    don't know why this is causing pselect to return, as this is one is
    opened O_RDONLY.

    At least now I know what the source of the issue is, and how to prevent
    it...