?
Solved

Never ready to read

Posted on 1998-04-24
12
Medium Priority
?
290 Views
Last Modified: 2010-04-15
Hi, I've taken many of your suggestions already and here is
the new improved version! Unfortunately it still acts like stdin is never ready to be read from, any suggestions? The other socket works just fine for reading etc...

void ConnectionIO(Sock *NSock)
             /* In this function, first we set up everything for our
                select calls. Then we loop, first reading in the data
                that needs to be read, then writing out any buffers */
{
  fd_set rset;
  int i, result;
  Sock Input;

  InitSock(&Input);
  Input.sock_fd = STDIN_FILENO;
  Input.name = "Standard Input, FUN!";
  Input.out_fd = NSock->sock_fd;                              NSock->out_fd = STDOUT_FILENO;
  FD_ZERO(&rset);
  FD_SET(STDIN_FILENO, &rset); /* 0 is stdin */
  FD_SET(NSock->sock_fd, &rset);

  while(1)
  {
    result = select(NSock->sock_fd + 1, &rset, NULL, NULL, NULL);

    if(result < 0) /* Whoops, looks like we've got an error */                          
      perror("JWClient:");
      exit(1);
    }
    if (FD_ISSET(NSock->sock_fd, &rset))
      ReadSock(NSock);
    if (FD_ISSET(Input.sock_fd, &rset))
      ReadSock(&Input);
  } /* While */
} /* ConnectionIO */

                               
0
Comment
Question by:jwilcox
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 3
  • +2
12 Comments
 
LVL 5

Expert Comment

by:julio011597
ID: 1255686
I can see a few problems in your function:

1. a NULL pointer as a timeout in select() - at least on my OS - makes your function block indefinitely... is this what happens? To poll, the timeout parameter should be a nonzero value and point to a zero-valued timeval structure.

2. if the time limit expires before any event occurs that would cause one of the masks to be set to a non-zero value, select() completes successfully and returns 0 (zero). Your code is exiting with an error notification, instead.

3. you should not loop around FD_ISSET(); just give it the file descriptor to check:

if(FD_ISSET(NSock->sock_fd, &rset)) ReadSock(NSock->sock_fd);
0
 
LVL 5

Expert Comment

by:julio011597
ID: 1255687
Hey jwilcox, did that help? did i miss the point?
0
 
LVL 1

Author Comment

by:jwilcox
ID: 1255688
Actually, while I definatly appreciate the help, it hassn't helped. I have it as NULL because I do want it to block indefinitly...and even when I axed the loop when i gets to the FD to check it, it still acts like that bit wasn't changed...even though if I do a read right before that select call, I get plenty of data, but take that read out and depend only on select, and down the drain it goes...here is some more info from GDB if this will help you at all...
 NSock->sock_fd = 9  rset = {fds_bits = {513, 0 <repeats 31 times>} }
 
 That rset is after both the calls to FD_SET()...thanks in advance.
 
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 4

Expert Comment

by:jos010697
ID: 1255689
I noticed one thingy; shouldn't the select line read:

    result = select(NSock->sock_fd+1, &rset, &wset, NULL, NULL);

i.e. the first parameter equals the _number_ of file descriptors to check ...

kind regards,

Jos aka jos@and.nl

ps. It still doesn't explain why stdin is never readable though ...
0
 
LVL 1

Author Comment

by:jwilcox
ID: 1255690
Edited text of question
0
 
LVL 5

Expert Comment

by:julio011597
ID: 1255691
This may sound stupid, but should that work for stdin and stdout after all?
I mean, they are file descriptors, not socket descriptors!?

I guess i'm going to dive the Sockets FAQ again :)
0
 
LVL 4

Expert Comment

by:jos010697
ID: 1255692
Julio, you've got a point here: on (any? every?) unix box sockets, files, etc are
all implemented as streams. Not so on NT or Windows/95 boxes; I've seen it
actually happen (someone tried to fdopen a socket on an NT box). There's
a disctinction between file descriptors and socket descriptors on those machines ...

I don't know what moron invented that ...

kind regards,

Jos aka jos@and.nl
0
 
LVL 2

Expert Comment

by:seedy
ID: 1255693
Here is an excerpt from man pages for select.
"On successful completion, the objects pointed to by the readfs,
writefs, and errorfds arguments are ***modified*** to indicate
which file descriptors are ready for reading, ready for writing,
or have an error condition pending, respectively."

This means, in your code, after returning from select, the
content of  "rset" is modified! - or the bit is set ONLY for
the FD that is ready for a read.  On next iteration, you
will only check for that FD!

So can you place the FD_ZERO, FD_SET statements just before the
select call - inside the loop - and tell us what happens?
0
 
LVL 4

Expert Comment

by:jos010697
ID: 1255694
Julio, you've got a point here: on (any? every?) unix box sockets, files, etc are
all implemented as streams. Not so on NT or Windows/95 boxes; I've seen it
actually happen (someone tried to fdopen a socket on an NT box). There's
a disctinction between file descriptors and socket descriptors on those machines ...

I don't know what moron invented that ...

kind regards,

Jos aka jos@and.nl
0
 
LVL 1

Author Comment

by:jwilcox
ID: 1255695
Seedy was correct...if you don't re-setup your FD_ZERO FD_SET everytime it will have the problems, but now it works fine, so thank you very much!
0
 
LVL 1

Expert Comment

by:szetoa
ID: 1255696
Hi jwilcox,

I have a comment about your routine and hope this helps.
The select() looks OK to me except where the data for the
stdin come from.  I did not see any statement 'reading'
from stdin.  If there is no data 'already' in stdin, the
select() will block indefinitely.  If you are running your
program under UNIX, you may try:

    echo "some garbage" | pgm

Assuming your program name is 'pgm'.  I think in this case,
you will see your select() statement works.

Hope this help.
0
 
LVL 2

Accepted Solution

by:
seedy earned 400 total points
ID: 1255697
You need to re-initialize the read, write, error fd sets every
time you call the 'select' statement. Place the FD_ZERO, FD_SET
statements just before the select call, inside the loop.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.
Suggested Courses

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question