• C

Never ready to read

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 */

                               
LVL 1
jwilcoxAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

julio011597Commented:
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
julio011597Commented:
Hey jwilcox, did that help? did i miss the point?
0
jwilcoxAuthor Commented:
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
Managing Security Policy in a Changing Environment

The enterprise network environment is evolving rapidly as companies extend their physical data centers to embrace cloud computing and software-defined networking. This new reality means that the challenge of managing the security policy is much more dynamic and complex.

jos010697Commented:
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
jwilcoxAuthor Commented:
Edited text of question
0
julio011597Commented:
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
jos010697Commented:
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
seedyCommented:
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
jos010697Commented:
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
jwilcoxAuthor Commented:
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
szetoaCommented:
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
seedyCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.