Solved

Never ready to read

Posted on 1998-04-24
12
287 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
Industry Leaders: 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 100 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

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!

Question has a verified solution.

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

Suggested Solutions

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…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand and use structures 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.

739 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