Article 12178 of comp.lang.perl:
Newsgroups: comp.lang.perl
Path: feenix.metronet.com!news.utdallas.edu!corpgate!bnrgate!bnr.co.uk!pipex!howland.reston.ans.net!cs.utexas.edu!csc.ti.com!tilde.csc.ti.com!cauldron!ra.csc.ti.com!enterprise!sunds
From: sunds@asictest.sc.ti.com (David M. Sundstrom)
Subject: Re: How to find if there's something on a Sock
Message-ID: <CnJx9G.550@csc.ti.com>
Sender: usenet@csc.ti.com
Nntp-Posting-Host: enterprise.asic.sc.ti.com
Reply-To: sunds@asictest.sc.ti.com
Organization: Texas Instruments
References: <ANDREW.94Mar31115422@neptune.dcs.qmw.ac.uk>
Date: Thu, 31 Mar 1994 23:00:48 GMT
Lines: 83

In article 94Mar31115422@neptune.dcs.qmw.ac.uk, andrew@dcs.qmw.ac.uk (Andrew Smallbone) writes:
> 
> Can anyone tell me how to find if there is something to read on a
> socket?  
> 
> I've been looking at:
> 		select(RBITS,WBITS,EBITS,TIMEOUT)
> and		&FD_ISSET()  - from /usr/include/sys/types.h
> 
> But I can't figure out how to create the structures correctly? Any Ideas?
> 
> I've got a socket that I both read and (occasionally) write too and
> want to check when a message has been received without waiting on a
> read() until something comes in.  The messages haven't got newlines in
> so I can't do:
> 	while (<Socket>) {
> 		# process message code
> 	};
> 


Assuming your socket filehandle is called "SOCK", then:


    vec($rin,fileno(SOCKET),1) = 1;
    select($rout=$rin, undef, undef, $Timeout);
    $len=sysread(SOCKET,$buf,$buflen);

will block until something is there, unless you timeout.  You
can use a timeout of zero to check without blocking.  Use a timeout
of undef to wait forever.

The cool thing about select is that you can wait on more than
one thing, include other filehandles like STDIN:

   vec($rin1,fileno(SOCK1),1) = 1;
   vec($rin2,fileno(SOCK2),1) = 1;

   $rin = $rin1 | $rin2;

   for (;;) {

      select($rout=$rin, undef, undef, undef);


         if (vec($rout,fileno(SOCK1),1)) {

             ### do SOCK1 things

         }


         if (vec($rout,fileno(SOCK2),1)) {

             ### do SOCK2 things

         }
   }


Unbuffering your filehandles prior to using select will likely
be required:

  select((select(SOCK), $|=1)[$[]);

Which may be more clearly written as:

local($savehandle)=select(SOCK);
$|=1;  ## unbuffer SOCK
select($savehandle);  ## restore previously selected handle

Be certain not to mix sysread with other input mechanisms (such
as <SOCK> or read()).  


-David