Problem with named pipes and select - Linux

This is a discussion on Problem with named pipes and select - Linux ; I have a server process selecting on a named pipe that multiple clients write to. Whenever I close the file descriptor for the pipe in one of the clients the select in the server immediately returns even though the other ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: Problem with named pipes and select

  1. Problem with named pipes and select

    I have a server process selecting on a named pipe that multiple clients
    write
    to. Whenever I close the file descriptor for the pipe in one of the
    clients
    the select in the server immediately returns even though the other
    client
    has the pipe open for writing. How could I get select to wait
    for data to become from the remaining client instead or exiting right
    away?

    The "ready" descriptor is in the read descriptors set, not exception
    descriptor set.

    static fd_set rfds, efds;
    FD_ZERO(&rfds);
    FD_ZERO(&efds);
    int maxfd=0;
    for( I loop over all of my pipes here ) {
    int fd = the descriptor for my pipe;
    FD_SET(fd, &rfds);
    FD_SET(fd, &efds);
    if(fd>maxfd) {
    maxfd=fd;
    }
    }
    assert(maxfd);

    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = milliseconds * 1000;

    int retval = select(maxfd+1, &rfds, NULL, &efds,
    milliseconds<0?NULL:&tv);
    if (retval>0) {

    2.4.21, /libc 2.3.2

    Thank you.


  2. Re: Problem with named pipes and select


    snd...@gmail.com wrote:
    > I have a server process selecting on a named pipe that multiple clients
    > write
    > to. Whenever I close the file descriptor for the pipe in one of the
    > clients
    > the select in the server immediately returns even though the other
    > client
    > has the pipe open for writing. How could I get select to wait
    > for data to become from the remaining client instead or exiting right
    > away?


    (Instead of blocking waiting for the input that is not in the pipe)

    >
    > The "ready" descriptor is in the read descriptors set, not exception
    > descriptor set.


    I suppose one "solution" would be to close the read pipe in the server
    and reopen it.
    Unfortunately that introduces a race condition and if the other client
    writes to
    the pipe between close and open on the pipe in the server it will
    receive SIGPIPE
    that I'd have to handle. Any cleaner way to deal with this?

    >
    > static fd_set rfds, efds;
    > FD_ZERO(&rfds);
    > FD_ZERO(&efds);
    > int maxfd=0;
    > for( I loop over all of my pipes here ) {
    > int fd = the descriptor for my pipe;
    > FD_SET(fd, &rfds);
    > FD_SET(fd, &efds);
    > if(fd>maxfd) {
    > maxfd=fd;
    > }
    > }
    > assert(maxfd);
    >
    > struct timeval tv;
    > tv.tv_sec = 0;
    > tv.tv_usec = milliseconds * 1000;
    >
    > int retval = select(maxfd+1, &rfds, NULL, &efds,
    > milliseconds<0?NULL:&tv);
    > if (retval>0) {
    >
    > 2.4.21, /libc 2.3.2
    >
    > Thank you.


    Should I have asked on the kernel NG since there's hardly any glibc
    glue on top of
    mkfifo/select ?


  3. Re: Problem with named pipes and select

    Hello,

    > I have a server process selecting on a named pipe that multiple clients
    > write
    > to. Whenever I close the file descriptor for the pipe in one of the
    > clients
    > the select in the server immediately returns even though the other
    > client
    > has the pipe open for writing. How could I get select to wait
    > for data to become from the remaining client instead or exiting right
    > away?


    That's the expected behavior. Actually, the file descriptor is
    readable, but /read()/ shall return 0.

    So the solution in your case is, I guess, to /read()/ whenever the file
    descriptor becomes readable. However, you should take into account that
    /read()/ may return 0, corresponding to a client that has closed the
    pipe. It's merely a matter of form. You won't have likely any further
    processing; you just have to ensure that it does not fool your logic
    that may expect /read()/ to return 1 or more bytes.

    HTH,
    Loic.


  4. Re: Problem with named pipes and select


    snd...@gmail.com wrote:
    > I have a server process selecting on a named pipe that multiple clients
    > write
    > to. Whenever I close the file descriptor for the pipe in one of the
    > clients
    > the select in the server immediately returns even though the other
    > client
    > has the pipe open for writing. How could I get select to wait
    > for data to become from the remaining client instead or exiting right
    > away?


    (Instead of blocking waiting for the input that is not in the pipe)

    >
    > The "ready" descriptor is in the read descriptors set, not exception
    > descriptor set.


    I suppose one "solution" would be to close the read pipe in the server
    and reopen it.
    Unfortunately that introduces a race condition and if the other client
    writes to
    the pipe between close and open on the pipe in the server it will
    receive SIGPIPE
    that I'd have to handle. Any cleaner way to deal with this?

    >
    > static fd_set rfds, efds;
    > FD_ZERO(&rfds);
    > FD_ZERO(&efds);
    > int maxfd=0;
    > for( I loop over all of my pipes here ) {
    > int fd = the descriptor for my pipe;
    > FD_SET(fd, &rfds);
    > FD_SET(fd, &efds);
    > if(fd>maxfd) {
    > maxfd=fd;
    > }
    > }
    > assert(maxfd);
    >
    > struct timeval tv;
    > tv.tv_sec = 0;
    > tv.tv_usec = milliseconds * 1000;
    >
    > int retval = select(maxfd+1, &rfds, NULL, &efds,
    > milliseconds<0?NULL:&tv);
    > if (retval>0) {
    >
    > 2.4.21, /libc 2.3.2
    >
    > Thank you.


    Should I have asked on the kernel NG since there's hardly any glibc
    glue on top of
    mkfifo/select ?


+ Reply to Thread