astanley has asked for the wisdom of the Perl Monks concerning the following question:

Monks, I have been stuck on this problem for the good majority of a week now and cannot explain it. I have developed a client/server application useful for CGI scripts that I personally wanted to run with root privileges but not directly. This has allowed me to run a server as root and install my own security checking rather than rely on something like suexec or suidperl. Anyway my trouble begins with a function that I created that listens for a "termination" message from the client before logging the conversation as a success (this also listens for "resend" messages much like TCP error-control). The function follows:
sub FinishUp { my ($clientid) = @_; my $incoming=""; while ( (sysread $clientid, $incoming, 1024) && != 0 ) { print "Received Response from $clientid: $incoming\n"; if ($incoming =~ /Resend/) { return "yes", "yes"; } if ($incoming =~ /Finished|OK/) { return "no", "no"; } } }
The strange and unexplainable part is...this works perfect for the majority of functions I call it from, however, there are 3 of the approximately 20 functions where the finishup function exits with this error message: Use of uninitialized value in integer ne (!=) at common.pl line 250. I fail to understand this because the finishup function is called the exact same way with the exact same parameters (the client ID) everytime. use strict and perl -w are outputting just that error message - everything else runs perfect. If anyone might be able to shed a little light on this I would greatly appreciate it. -Adam Stanley Nethosters, Inc.

Replies are listed 'Best First'.
Re: Unexplainable Client/Server trouble
by dws (Chancellor) on Apr 03, 2001 at 00:45 UTC
    sysread returns undef on error. Chances are good that you're getting an error.

    Save the return value from sysread, and explicitly test for undef. </code> You might find something of interest in $!

      Is it possible to determine what is causing the error? I've printed the $clientid and it returns a correct reference (at least the same as went in the other side when the function was called)...and the function works perfect for 17 out of the 20 functions...the clientid doesn't seem to be part of the error and I don't know what else would cause sysread to fail.
      -Adam Stanley
      Nethosters, Inc.
Re: Unexplainable Client/Server trouble
by astanley (Beadle) on Apr 03, 2001 at 01:04 UTC
    UPDATE: I tested the $! after receiving the error from sysread and discovered it's retuning a Broken Pipe. Has anyone else experienced this? I don't understand what would be causing the problem only in the specific functions. Any help or pointers are still appreciated.
    -Adam Stanley
    Nethosters, Inc.

      I thought that "broken pipe" only happened when writing to a pipe (and my quick review of some documentation supports that)...

      But it would make sense that a socket could give you "broken pipe" on read if the connection was broken badly (as opposed to the connection being shut down normally which should just generate "end of file" which sysread will return as 0 and not undef).

      So, for example, the connection timing out or the route to the client being lost (to the point of generating "host unreachable" via ICMP), etc. could probably generate this.

              - tye (but my friends call me "Tye")
      Let's assume for a moment that "Finished" means that the other end of the socket is declaring that they're done, and that they'll next close the socket. If you have a code path that takes you back through this routine after the other end has closed the socket, you'll see a broken pipe.

      See tye's response below.

      I've run test from the client side of the connection - the failure in execution stops between two lines ... one of which seems to be executed, the second of which doesn't. The two lines are syswrite and sysread. The write apparently goes through and the server reacts, however when the read is called the script dies - even when run with something like sysread(...) || print "im dying"; The script doesn't output the I'm dying. I've examined $! and the return code of the sysread and both are empty strings. I do not know what else I can do to debug this so hopefully someone will have an idea. Sorry for the hundred posts.

      -Adam Stanley
      Nethosters, Inc.

        Writing to a pipe that has no readers can generate a SIGPIPE signal which will kill your program. You can prevent this with $SIG{PIPE}= 'IGNORE'; and then syswrite will return undef and $! will be "broken pipe".

                - tye (but my friends call me "Tye")
Re: Unexplainable Client/Server trouble
by astanley (Beadle) on Apr 03, 2001 at 00:41 UTC
    Sorry I made a typo while modifying the function before posting...the while line should read:
    while ( (sysread, $clientid, $incoming, 1024) != 0) {
    Thanks dws for pointing that out.

    -Adam Stanley
    Nethosters, Inc.