It is currently Mon, 30 Mar 2020 22:26:55 GMT



 
Author Message
 select() returns on unwanted fd's
I am using select(2) in a program that forks another process and duplicates
its stdin & stderr. Something like this:

/* Pseudocode follows */
pipe();

fork();

if (child) {
   close_some_pipe_ends();
   dup_my_std(in, out, err);
   close_my_std(in, out, err);
   execl(...);
else if (parent) {
/* End of pseudocode, but this is actually part of a function */
  char
    ebuf[MAXBUFF],
    ibuf[MAXBUFF],
    ttyin[80];

  int
    n,
    rfd,  /* Read fd from child's stdout */
    wfd,  /* Write fd to child's stdin */
    efd,  /* Read fd from child's stderr */
    maxfdp1;

  fd_set
    ready,
    readfrom;

  struct timeval
    tmout;

  maxfdp1 = (rfd > wfd) ? ((rfd > efd) ? rfd : efd)
    : ((wfd > efd) ? wfd : efd);
  maxfdp1++;

  FD_ZERO(&readfrom);
  FD_SET(rfd, &readfrom);
  FD_SET(efd, &readfrom);

  tmout.tv_sec = 0;
  tmout.tv_usec = 0;

  fcntl(rfd,F_SETFL,O_NDELAY);  /* Don't wait on reads */
  fcntl(efd,F_SETFL,O_NDELAY);

  do {
    ready = readfrom;
    if ((n = select(maxfdp1, &ready, (fd_set *) 0, (fd_set *) 0, &tmout)) < 0)
      break;
    if (FD_ISSET(rfd, &ready)) {
      if ((n = read(rfd, ibuf, MAXBUFF)) > 0) {
        ibuf[n] = '\0';
        printf("%s", ibuf);
        fflush(stdout);
      }
      else
        return(-1);
    }
    if (FD_ISSET(efd, &ready)) {
      errno = 0;
      if ((n = read(efd, ebuf, MAXBUFF)) > 0) {
        ebuf[n] = '\0';
/* Here I plan to insert some analyzis on the error messages, but right now
   I just print them on the tty */
        fprintf(stderr, "%s", ebuf);
        fflush(stderr);
      }
      else
        return(-2);
    }
  } while (FD_ISSET(rfd, &readfrom) || FD_ISSET(efd, &readfrom));
  return(0);
...

From what I understand, select() should return ONLY when there is some data
to read on rfd or efd. But select() seems to return when any of the file-
descriptors 0..maxfpd1 is ready for reading or writing. In this range we
can find the parents stdin and stdout, and select() returns on these.

I want to keep parents stdin and stdout open, but not select() to take any
notice of them. What am I doing wrong? How should I do?

Many thanks to anyone who knows and answer me.

                /Thomas
--
_______________________________________________________________________________
                             |            Thomas Engstrom | +46 13 28 1260
               X             |    University of Linkoping | fax: +46 13 28 2800
                             | S-581 83 Linkoping, SWEDEN | Th...@LIDAC.LiU.se



 Sat, 07 Oct 1995 19:27:03 GMT   
 select() returns on unwanted fd's
() [...]
() FD_ZERO(&readfrom);
() FD_SET(rfd, &readfrom);
() FD_SET(efd, &readfrom);
() tmout.tv_sec = 0;
() tmout.tv_usec = 0;
() [...]
() do {
()   ready = readfrom;
()   if ((n = select(maxfdp1, &ready, (fd_set *) 0, (fd_set *) 0, &tmout)) < 0)
()     break;
()   if (FD_ISSET(rfd, &ready)) {
()     [...]
()   }
()   if (FD_ISSET(efd, &ready)) {
()     [...]
()   }
() } while (FD_ISSET(rfd, &readfrom) || FD_ISSET(efd, &readfrom));

I can think of at least two reasons why the program fragment doesn't
behave like you expect.

First, specifying a timeout with both tv_sec and tv_usec equal to zero
causes the call to select() to return immediately, i.e. you are just
polling the file descriptors without waiting for them to become ready
(busy-waiting).  If you don't want a timeout, use (struct timeval *)0.

Second, you have to (re-)initialize the file descriptor masks prior to
each call to select(), not just once in the beginning.  The file
descriptor masks are input/output parameters, i.e. select() overwrites
the bits you set.



 Sun, 08 Oct 1995 18:29:20 GMT   
 select() returns on unwanted fd's

 Thomas> From what I understand, select() should return ONLY when
 Thomas> there is some data to read on rfd or efd. But select() seems
 Thomas> to return when any of the file- descriptors 0..maxfpd1 is
 Thomas> ready for reading or writing. In this range we can find the
 Thomas> parents stdin and stdout, and select() returns on these.

From what you understand, you're correct except that you didn't
read the part about the timeout value.  If you pass a null pointer
then select() will block forever until there is something on one
of the selected file descriptors.  If, however, you pass a pointer
to a struct timeval with zeroes in it, you are effecting a poll; which
means to say that select() will return immediately upon setting the
fd_set structures accordingly.
--
Georg S. Nikodym  -  (416) 272-5198 / 720-4729
Noweh Software - Mississauga, Ontario, CANADA
UUCP:   {comspec.com, lsuc.on.ca, uunet.ca}!noweh!georgn
RFC822: geo...@noweh.COM



 Tue, 10 Oct 1995 13:14:46 GMT   
 
   [ 3 post ] 

Similar Threads

1. RH 2.2.5 select() only returns 1 FD as ready even when more are

2. How many FD's can select() handle?

3. open() doesn't return lowest avail fd on Solaris

4. select() doesn't return on socket descriptor

5. Select returns data available read returns no data

6. When do read() return 0 despite that select() returned 1

7. Does select() return if the FD changed before select() was called?

8. Best way to find approp. fd's after returning from select(),


 
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software