Behavior of select() - Unix

This is a discussion on Behavior of select() - Unix ; I'm learning how to use select(), and I have a program that is behaving in a way I don't understand on my FreeBSD machine. My code opens two regular files on disk, and then calls whichisready(), which returns a file ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: Behavior of select()

  1. Behavior of select()




    I'm learning how to use select(), and I have a program that is behaving
    in a way I don't understand on my FreeBSD machine. My code opens two
    regular files on disk, and then calls whichisready(), which returns a file
    descriptor of a file that is ready for reading.

    I expect the program to open up both files, read the first one until it
    is done, then read file2 until it is done, then end.

    Instead, it seems to prints out the contents of the first file, and
    then just seems to pause without delivering anything to stdout. When I
    run truss, this is the output I get:



    read(0x4,0xbfbfeb40,0x1) = 0 (0x0)
    select(5,{3 4},0x0,0x0,0x0) = 2 (0x2)
    read(0x4,0xbfbfeb40,0x1) = 0 (0x0)
    select(5,{3 4},0x0,0x0,0x0) = 2 (0x2)
    read(0x4,0xbfbfeb40,0x1) = 0 (0x0)
    select(5,{3 4},0x0,0x0,0x0) = 2 (0x2)
    read(0x4,0xbfbfeb40,0x1) = 0 (0x0)
    select(5,{3 4},0x0,0x0,0x0) = 2 (0x2)
    read(0x4,0xbfbfeb40,0x1) = 0 (0x0)
    select(5,{3 4},0x0,0x0,0x0) = 2 (0x2)
    read(0x4,0xbfbfeb40,0x1) = 0 (0x0)
    select(5,{3 4},0x0,0x0,0x0) = 2 (0x2)
    read(0x4,0xbfbfeb40,0x1) = 0 (0x0)
    select(5,{3 4},0x0,0x0,0x0) = 2 (0x2)
    read(0x4,0xbfbfeb40,0x1) = 0 (0x0)


    So it seems like select thinks that file1 is ready for reading, even
    though the program has already read the whole file. It runs read,
    which returns nothing, and then the cycle repeats. This program DOES work
    with 2 FIFOs. Why doesn't it work with 2 regular disk files?







    This is my code:

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


    int whichisready(int fd1, int fd2) {
    int maxfd;
    int nfds;
    fd_set readset;

    if ((fd1 < 0) || (fd1 >= FD_SETSIZE) ||
    (fd2 < 0) || (fd2 >= FD_SETSIZE)) {
    errno = EINVAL;
    return -1;
    }
    maxfd = (fd1 > fd2) ? fd1 : fd2;
    FD_ZERO(&readset);
    FD_SET(fd1, &readset);
    FD_SET(fd2, &readset);
    nfds = select(maxfd+1, &readset, NULL, NULL, NULL);
    if (nfds == -1)
    return -1;
    if (FD_ISSET(fd1, &readset))
    return fd2;
    if (FD_ISSET(fd2, &readset))
    return fd1;
    errno = EINVAL;
    return -1;
    }


    int main()
    {


    int fd1, fd2, bytes_read;
    fd_set readset;
    char buffer[100];
    int ready;
    bzero (buffer, 100);
    fd1 = open ( "/tmp/file1", O_RDONLY);
    fd2 = open ( "/tmp/file2", O_RDONLY);

    while ((ready = whichisready ( fd1, fd2)) > 0) {

    while ( (bytes_read = read (ready, buffer, 1)) > 0 )
    write (1, buffer, bytes_read);
    }

    return 0;
    }




    Note: Please remove the -nospam- in my address if you want to respond via
    email. Thanks.


  2. Re: Behavior of select()

    Jamie Ostrowski wrote:
    >
    >
    >
    > I'm learning how to use select(), and I have a program that is
    > behaving in a way I don't understand on my FreeBSD machine. My code
    > opens two regular files on disk, and then calls whichisready(), which
    > returns a file descriptor of a file that is ready for reading.
    >

    File descriptors associated with regular files always select true for
    read and write.

    --
    Ian Collins.

  3. Re: Behavior of select()

    On Apr 11, 7:31 pm, Jamie Ostrowski wrote:

    > I expect the program to open up both files, read the first one until it
    > is done, then read file2 until it is done, then end.


    Even after you're done reading a file, it's still ready.

    > Instead, it seems to prints out the contents of the first file, and
    > then just seems to pause without delivering anything to stdout. When I
    > run truss, this is the output I get:


    If a 'read' operation will immediately return an error, such as end-of-
    file, then the file descriptor is ready to be read. There is nothing
    to wait for, the 'read' should be done immediately. You don't need to
    wait to find out that you are the end of the file.

    DS

  4. Re: Behavior of select()

    Jamie Ostrowski wrote:

    > if (FD_ISSET(fd1, &readset))
    > return fd2;
    > if (FD_ISSET(fd2, &readset))
    > return fd1;


    Likely the code would work better if it would read like:

    if (FD_ISSET(fd1, &readset))
    return fd1;
    if (FD_ISSET(fd2, &readset))
    return fd2;


    Do you notice the two changes I made?

    Hope this helps ... Rainer

+ Reply to Thread