Using select() to see if input available

Using select() to see if input available

Post by John J. Ribe » Sun, 19 Jun 1994 05:12:23



I'm trying to use select() to determine if there is input available. I do
not quite understand the man page. I simply want to know if a command has
been executed with redirection from a file:

$ cmd        # here there is no input file specified, so how do I know?
$ cmd < file # I have specifed a valid file. Will select know? How?

since I am quering read on stdin wouldn't the select be:
-------------
   fd_set  rdfd_set;
   int     nfdready;
   timeval tv;

memset(&tv, 0, sizeof(tv));
FD_ZERO(&rdfd_set);
FD_SET(0, &rdfd_set);   /* do I have to set this bit to ensure proper op? */

nfdready = select(1, &rdfd_set, NULL, NULL, &tv);

if (FD_ISSET(0, &rdfd_set)) printf("Input waiting to be read!\n");
else printf("No input specified");

--------

 
 
 

Using select() to see if input available

Post by Kari E. Hurt » Sun, 19 Jun 1994 16:21:42



?I'm trying to use select() to determine if there is input available. I do
?not quite understand the man page. I simply want to know if a command has
?been executed with redirection from a file:

?$ cmd        # here there is no input file specified, so how do I know?
?$ cmd < file # I have specifed a valid file. Will select know? How?

In both case you HAVE input available:
        In first case from your terminal
        In second case from that file (EOF status is available if nothing
                more).

You perhaps want look, that is standard input terminal?
Look isatty(3) function.
--
- Kari E. Hurtta                             /  El?m? on monimutkaista


 
 
 

Using select() to see if input available

Post by Mark Brop » Mon, 20 Jun 1994 00:06:05



Quote:>I'm trying to use select() to determine if there is input available. I do
>not quite understand the man page. I simply want to know if a command has
>been executed with redirection from a file:
>$ cmd        # here there is no input file specified, so how do I know?
>$ cmd < file # I have specifed a valid file. Will select know? How?
>since I am quering read on stdin wouldn't the select be:
>-------------
>   fd_set  rdfd_set;
>   int     nfdready;
>   timeval tv;
>memset(&tv, 0, sizeof(tv));

This will tell select to wait for 0 seconds and 0 microsecs.
If you want it to wait indefinately, pass a NULL as the last argument of
select().

Quote:>FD_ZERO(&rdfd_set);
>FD_SET(0, &rdfd_set);   /* do I have to set this bit to ensure proper op? */
>nfdready = select(1, &rdfd_set, NULL, NULL, &tv);

                   ^
This is the highest file descriptor you would want to check, so 1 should
be fine, but if you are using other file descriptors, you will want to
set it higher. Usually to what is returned by getdtablesize();

Quote:>if (FD_ISSET(0, &rdfd_set)) printf("Input waiting to be read!\n");
>else printf("No input specified");

This is fine.

Hope this helps.

        Mark Brophy

 
 
 

Using select() to see if input available

Post by John Hasca » Mon, 20 Jun 1994 00:48:46




}>I'm trying to use select() to determine if there is input available.
}>$ cmd        # here there is no input file specified, so how do I know?
}>$ cmd < file # I have specifed a valid file. Will select know? How?
}>memset(&tv, 0, sizeof(tv));
}This will tell select to wait for 0 seconds and 0 microsecs.
}If you want it to wait indefinately, pass a NULL as the last argument of
}select().

   Waiting 0.0 is probably what he wanted (a poll).  This is a rather
   bizarre way to determine if stdin is redirected (as somebody else
   already pointed out, "isatty()" is the more conventional way).

Quote:}>nfdready = select(1, &rdfd_set, NULL, NULL, &tv);
}                   ^
}This is the highest file descriptor you would want to check, so 1 should
}be fine, but if you are using other file descriptors, you will want to
}set it higher. Usually to what is returned by getdtablesize();

    This can be extremely wasteful (esp. in systems with lots of
    FDs to check, i.e., OSF/1 with 4096).  Better to keep a
    "maxfd" variable.  BTW, it's not the highest FD to check, it
    is the count of FDs to check (so it has to be 1 greater than
    the highest FD to check).

John
--
John Hascall                   ``An ill-chosen word is the fool's messenger.''
Systems Software Engineer
Project Vincent
Iowa State University Computation Center  +  Ames, IA  50011  +  515/294-9551

 
 
 

Using select() to see if input available

Post by Casper H.S. D » Mon, 20 Jun 1994 00:49:17



>>nfdready = select(1, &rdfd_set, NULL, NULL, &tv);
>               ^
>This is the highest file descriptor you would want to check, so 1 should
>be fine, but if you are using other file descriptors, you will want to
>set it higher. Usually to what is returned by getdtablesize();

You make two mistakes here that should be eradicated:

        - the first argument to select is *not* the highest filedescriptor
          you are interested in, it is the number of bits select will
          copyin/out and check.
          The number should be ONE MORE than the highest fd you're
          interested in.
        - DO NOT USE getdtablesize() as first argument to select.
          getdtablesize() is not a constant.  It can vary wildly from
          release to release. However, the size of the fd_sets is
          fixed at compile time.  When at one point in future
          getdtablesize() start to exceed the compiled in value,
          select will start looping with EBADFs.  (I've seen it
          happen).

The first argument to select should therefor be:

        - the highest descriptor you're interested in PLUS ONE.
    or
        - FD_SETSIZE if you're lazy and your system defines
          it.
    or
        - sizeof(int)*CHAR_BIT if you're lazy and using an OS with
          old one-integer select and have CHAR_BIT defined
    or
        - sizeof(int)*NBBY if you're lazy and using an OS with
          old one-integer select and have NBBY defined
    or
        - sizeof(int) * 8 (last case + NBBY and CHAR_BIT not defined)

The use of getdtablesize() for any purpose is evil, IMHO.
(Even in the standard close loop).
And it's not portable.

Casper

 
 
 

1. Q: Using select() to wait for pending input.

I am trying to write C code to detect whether there is any pending input
on an input stream, such as stdin. Following the advice in the Unix
Programming FAQ, I wrote the following code, using select():

#include <stdio.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int favail(
        FILE            *pFile) {

        int             fd;
        fd_set          set;
        struct timeval  tv;
        int             result;

        fd = fileno(pFile);

        FD_ZERO(&set);
        FD_SET(fd, &set);

        /* don't wait */

        tv.tv_sec = 0;
        tv.tv_usec = 0;

        return select(fd + 1, &set, NULL, NULL, &tv);

int main(
        int             argc,
        char*           argv[]) {

        int             i;
        int             c;
        FILE*           sock;

        while (c != EOF) {

          if (favail(stdin)) {
            c = fgetc(stdin);
            printf("%c", c);
            fflush(stdout);

          }

        }

This code behaves a little unusually, and I don't understand why. If I
run it, and enter a line like "12345", and press return, it will print
"1". If I press return again, it will print "2345\n\n" (\n's representing
carriage returns). It continues with this sort of behaviour. When I type
in a line, it will print the first character, and will wait until I enter
another line before showing the rest.

Can anyone explain to me what is going on here?

Malcolm

2. free database software for Linux

3. Help using select() to see if chars are available for reading

4. MMDF Queue hacking

5. Linux ext2fs IFS for OS/2 : ext2-os2 0.3 available for testing

6. Stable Linux 2.2.x (SMP) with Apache

7. Linux ext2fs IFS for OS/2 - ext2-os2 V0.4 beta now available

8. Starr Office problem

9. Linux ext2fs IFS for OS/2 - ext2-os2 V0.8 now available

10. Linux ext2fs IFS for OS/2 : ext2-os2 V0.5 now available

11. Using IFS on Linux 1.3.48 - Help!

12. ext2 for Win95 (using IFS)

13. Non-blocking input after a select call