[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