Re: select + stderr

Jens.Toerring_at_physik.fu-berlin.de
Date: 01/21/05


Date: 21 Jan 2005 12:17:46 GMT

Thomas Beneke <thomas.beneke@web.de> wrote:
> I have a client - server, but this works only for stdout.

What works? What means stdout in the context of a server-client pair?

> What do I have
> to change . If I send a 'ls' to the server, I get the correct response
> on the client side. If I send a 'ls /sdfdsfdlfsdl' ( a non existing
> file), I get the error message on server side on stderr, but on client
> side on stdout.

> while (FD_ISSET(sockfd, &rfdset))

I don't understand what this is good for - using the FD_ISSET macro
only really makes sense *after* you called select().

> {
> if (select( fd+1 , &rfdset, NULL, NULL, NULL) < 0) {
> if (errno != EINTR) {
> fprintf(stderr,"select failed\n");
> exit(1);
> }
> }
> if (FD_ISSET(sockfd, &rfdset)) {
> if ( (numbytes = recv(sockfd, buffer, sizeof(buf), MSG_WAITALL))
> < 0 )

Are you sure the MSG_WAITALL is appropriate here? What is supposd to
happen when the message sent by the server is less than sizeof(buf)
bytes?

> {
> fprintf(stderr,"recv failed.\n");
> exit(1);
> }
> if ( numbytes ) {
> if ( (write(STDOUT_FILENO, buffer, numbytes)) <0) {
> fprintf(stderr,"send stdout failed\n");
> exit(1);
> }
> }
> else if (numbytes == 0 || errno != EWOULDBLOCK)

If recv() didn't return -1 the value of errno doesn't tell you anything,
you are never supposed to do anything with errno's value unless an error
happened. If you feel like checking for EWOULDBLOCK (BTW, it could also
be EAGAIN according to SUSv3) you need to do that further up where you
check 'numbytes' for a negative value.

> FD_CLR(sockfd, &rfdset);

If you call select() with a cleared fdset you tell it to wait for *no*
file descriptors to become ready for reading. I guess you do that because
of the bogus while loop condition at the start. You better make the while
loop an infinite loop (i.e. use "while(1)" and break from it once you find
that you recv() returned 0 (telling you that the other side closed the
socket).

> }

Before you call select() again you must set up the fdset anew - other-
wise the case that select() did return -1 with errno being set to EINTR
won't be dealt with correctly (or if you're dealing with more than a
single file descriptor you call select() on).

> }

If I guess correctly that you want to have your client send a shell
command to the server, have the server execute it by fork()ing and
exec()ing a shell and send back both what the server received from
both the stdout and stderr of the shell it spawned separately, then
you need two logical channels between the server and the client -
one for sending back the result from stdout and one for sending what
appeared on stderr. For that you need either two sockets or you must
develop some kind of protocol that allows the client to figure out
what was what. There's nothing magical about stdout and stderr, they
are just two different file descriptor - and when you have the server
send what it read from both these channels intermixed via a single
channel to the client, the client won't be able to untangle them.

The simplest solution is probably to open two sockets and have the
server write what it got from the stdout of the shell via one of the
sockets and what it read from stderr of the shell to the other one.
The client then listens on both these sockets, writing out what it
receives from the first one to its stdout and what it receives from
the second one to its stderr.
                                    Regards, Jens

PS: I hope you're aware of the security implications of such a server
running on your machine and have access to that server secured by a
password (which you better don't send unencrypted over the net!).

-- 
  \   Jens Thoms Toerring  ___  Jens.Toerring@physik.fu-berlin.de
   \__________________________  http://www.toerring.de


Relevant Pages

  • Reidrect stderr of child process
    ... I have inherited the maintenance of a client app and the associated server. ... Simply, the server waits for the client to trigger it; ... Save current STDERR, to be restored later. ...
    (microsoft.public.win32.programmer.networks)
  • Re: How to display binary file contents if it is stored in an integer array?
    ... a file to the server, then the server should display the content of ... What do you expect to display on stdout? ...
    (comp.lang.c)
  • Re: [QUIZ] Space Merchant (#71)
    ... Could you have the client pass you $stdout and $stdin, ... station (which causes the server to wait for input!) :-( ...
    (comp.lang.ruby)
  • Re: Writting a UDP server program under inetd/xinetd
    ... >> message to server, but server cannot send response by simply printf the ... >> message to stdout. ... >'printf' because it doesn't give you appropriate control. ... to opinions held by my employer, Sun Microsystems. ...
    (comp.unix.programmer)
  • Re: select + stderr
    ... What means stdout in the context of a server-client pair? ... >>file), I get the error message on server side on stderr, but on client ...
    (comp.unix.programmer)