[lsb-discuss] help needed regarding select API

Jeff Licquia jeff at licquia.org
Wed Jun 14 15:28:04 PDT 2006

On Wed, 2006-06-14 at 16:22 +0530, Nayyar Azam wrote:

> I am right now implementing test case for "select" API, and I have
> right now come across a very typical problem. Might be I am knowing
> less about select..or so.. 

Well, let's see.

> My problem is that I have created two files as follows...
> system("touch tmp1;echo absjkhsk>tmp1;chmod 400 tmp1");
> system("touch tmp2;echo jhagsakjg>tmp2;chmod 200 tmp2");
> Now I opened the files as follows..
> fd1=open("tmp1",O_RDONLY);
> fd2=open("tmp2",O_WRONLY);

Good so far.

> Now I added both the  file descriptors in "rfds" and "wfds" (Basically
> defined as "fd_set rfds,wfds; ") as follows...
> FD_SET(fd1,&rfds);
> n=n>fd1?n:fd1;
> FD_SET(fd2,&wfds);
> n=n>fd2?n:fd2;
> FD_SET(fd1,&wfds);
> n=n>fd1?n:fd1;
> FD_SET(fd2,&rfds);
> n=n>fd2?n:fd2;
> Where n is an integer. 

Here's where I start getting confused.  Didn't you just open fd1 to be
read-only, and fd2 to be write-only?  What possible good could it do to
add fd1 to the write set, or fd2 to the read set?

As a minor nit, n is most efficiently calculated as follows:

  n = fd1 > fd2 ? fd1 : fd2;

Since the actual values of fd1 and fd2 don't change, you don't need to
calculate the proper value of n with every FD_SET.

> Now I call the select function as follows.....
> retval=select(n+1,&rfds,&wfds,NULL,NULL);
> Now to my surprise fd_set "rfds" contain both fd1 and fd2 being
> set.(Moreover I can't write on to fd1 using "write" ..after select
> returns !!!)
> and fd_set "wfds" too contain both of the descriptors. Iam really
> surprised at results. 

I'm not.  fd1's presence in rfds, and fd2's presence in wfds, shouldn't
be surprising.  As for the rest, my select(2) man page says:

> Those  listed  in
> readfds will be watched to see if characters become available for read-
> ing (more precisely, to see if a read will not block - in particular, a
> file  descriptor  is also ready on end-of-file)...

That parenthesized section is the most important part.  A read on fd2
will not, in fact, block, nor will a write on fd1.  Rather, both will
return -1 immediately, with errno set to EBADF.

This is consistent with IEEE 1003.1, which defines "ready for [some
operation]" as not blocking for that operation, whether or not any data
would be transferred successfully.

More information about the lsb-discuss mailing list