user643605
user643605

Reputation: 213

Pipe and select : sample code not working

Am I missing something ?

I want to come out of select by calling write in another thread... It never comes out of select.

Code is tested on OSX snow.

fd_set rio, wio;

int pfd[2];

void test(int sleep_time)
{
sleep(sleep_time);

char buf[] = "1";

write(pfd[1], buf, 1);

}

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

{

char buff[80];
int ended = 0;

pipe(pfd);

FD_ZERO(&rio);
FD_ZERO(&wio);

FD_SET(pfd[1], &wio);   
FD_SET(pfd[0], &rio);

pthread_t tid; /* the thread identifier */
pthread_attr_t attr; /* set of thread attributes */
pthread_attr_init(&attr);

pthread_create(tid, NULL, test, 3);

while (!ended)
{
// Check my numbers ... they do not go over 1 ... so 2
if (select(2, &rio, &wio, NULL, 0) < 0)
    perror("select");
else
{
    if (FD_ISSET(pfd[1], &wio))
    {
        if ((read(pfd[0], &buff, 80))<0) 
               perror("read");
         ended = 1;
    }
 }

}

Upvotes: 0

Views: 698

Answers (1)

Chuck Buche
Chuck Buche

Reputation: 71

I believe you have 2 errors:

1 - your select call is limiting the check to a max of fd 2, where the pipe will probably have larger FDs since 0, 1, and 2 are already opened for stdin, stdout, stderr. The pipe FDs will presumably have fds 3 and 4 so you actually need to determine the larger of the 2 pipe FDs and use that for the limit in the select instead of 2.

int maxfd = pfd[1];
if( pfd[0] > maxfd ) {
    maxfd = pfd[0];
}
...

2 - After select returns, you are looking at the wio and pipe write FD when you need to instead look to see if there is anything available to READ:

        if (FD_ISSET(pfd[0], &rio)) {

Upvotes: 1

Related Questions