Barry Brevik <> wrote:
>> If Barry could provide a small, self contained script that
>> demonstrates the problem it might be a lot easier to see.
> 
> Brian makes a good point (because flushing STDOUT did not work, but I
> enjoyed learning about it). I wanted to avoid wasting bandwidth with
> a snippet, because the snippet is rather large.  

The an important part of creating a small self contained script that
demonstrates the problem is that the act of doing so can give you a
better understanding of your code as well as your problem. Sometimes
enough for you to discover the solution for yourself (it has for me on
numerous occasions). It is not just a question of saving bandwidth, or
making life easier for your audience.

> 
> To set this up, I'm posting the portion of a loop that listens on
> port 80, then forks a process to handle that connection. I post this
> because it may be relevant. P.S. there is a bunch of socket setup
> code that is missing, but this is a really common method that I used
> almost verbatim out of a book.    
> 
> The problem occurs in the subroutine (below) named client_chat. Any
> "print" statements in that routine must go to STDERR or they are not
> seen until *main process* (not child) terminates. Please be gentle;
> I'm rather new to Perl so the code may be amateurish, but I just love
> the language.    
> 
>   $nfound = select($sout = $sin, undef, undef, .25);
>   if (vec($sout, fileno(SERVER), 1))
>   {
>     $client_addr = accept(CLIENT, SERVER);
>     ($client_socket, $client_pip) = sockaddr_in($client_addr);
>     if ($client_pip)
>     {
>       $client_ip = inet_ntoa($client_pip);
> 
>       if ($client_pip)
>       {
>         unless (defined($kidpid = fork()))
>         {
>           print "failed to fork after client connect: $!";
>           next;
>         }
> 
>         if ($kidpid)
>         {
>           # If we were forking successful, just 'fire and forget'.
>           $SIG{$kidpid} = 'IGNORE';
>           close(CLIENT);
>         }
>         else
>         {
>           close(SERVER);
> 
>           client_chat();
> 
>           close(CLIENT);
>           exit;
>         }
>       }
>     }
>   }
> 
> 
> sub client_chat
> {
>   # Set up bitmask for client.
>   $cin = ''; vec($cin, fileno(CLIENT), 1) = 1;
> 
>   # Check to see if data is ready, and if so, read it.
>   # Do this until the timeout is reached, or we see two
>   # CRLF's in a row.
>   $loopstart = time(); $bufend = 0;
>   $bufr = ''; @bufr = (); $useragent = '';
> 
>   for (;;)
>   {
>     $nfound = select($cout = $cin, undef, undef, .01);
>     if (vec($cout, fileno(CLIENT), 1))
>     {
>       $rec = recv(CLIENT, $dread, 8192, 0);
>       $dread =~ s/\x0+//g;
>       $bufr .= $dread;
>       if ($bufr =~ /\r\n\r\n$/m) {$bufend = 1; last;}
>       $loopstart = time();
>     }
> 
>     if (time() - $loopstart >= $ctimeout)
>     {
>       print STDERR "timeout reached while waiting for client input";
>       last;
>     }
>  

I notice that your print statements do not have "\n", which would cause
normally cause STDOUT buffers to flush. It is quite common for STDERR
and STDOUT to have different buffering strategies. If you check you will
see (I hope) that all of the print statements in my example had "\n" at
the end which may explain why mine worked while yours didn't. For more
on flushing and buffers, see 'perldoc -q flush'.

Some other comments about your code:

You don't appear to be using "use strict; use warnings;", which you
should appear at the start of your code. (If you posted a complete
script there would be no uncertainty about whether you used them.)

Your code would be simpler if you used the IO modules (IO::Socket::INET,
IO::Select), as well as shorter. (I haven't seen any code that used vec
for years!)

Your timeout value in your select calls seems rather small, for no
reason that I can see.

$SIG{$kidpid} = 'IGNORE' should probably be $SIG{CHLD} = 'IGNORE'. %SIG
keys are signal names, not pids.

HTH

-- 
Brian Raven 



=================================
Atos Euronext Market Solutions Disclaimer
=================================
The information contained in this e-mail is confidential and solely for the 
intended addressee(s). Unauthorised reproduction, disclosure, modification, 
and/or distribution of this email may be unlawful.
If you have received this email in error, please notify the sender immediately 
and delete it from your system. The views expressed in this message do not 
necessarily reflect those of Atos Euronext Market Solutions.

L'information contenue dans cet e-mail est confidentielle et uniquement 
destinee a la (aux) personnes a laquelle (auxquelle(s)) elle est adressee. 
Toute copie, publication ou diffusion de cet email est interdite. Si cet e-mail 
vous parvient par erreur, nous vous prions de bien vouloir prevenir 
l'expediteur immediatement et d'effacer le e-mail et annexes jointes de votre 
systeme. Le contenu de ce message electronique ne represente pas necessairement 
la position ou le point de vue d'Atos Euronext Market Solutions.

_______________________________________________
ActivePerl mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to