// Make sure that a system call went well
// If a system call (say, fcntl()) fails
// it returns -1 and sets the errno
#define do_well(FX) (void)( (FX) < 0 ? (perror("System error"), \
_error("Failed system call " #FX " at line %d of ´%s'.\n", \
__LINE__, __FILE__),0) : 1)
// Obtains the IP address of the specified
// host. The host name may be specified
// either in the dot notation, or as a
// host "name".
// Name resolution is performed in the
// latter case.
IPaddress::IPaddress(const char * host_name)
{
// First check to see if the host
// name is specified in the IP address
// dot notation
if( (address = inet_addr(host_name)) != (unsigned long)(-1) )
return;
struct hostent *host_ptr = ::gethostbyname(host_name);
if( host_ptr == 0 )
_error("Host name '%s' cannot be resolved",host_name);
if( host_ptr->h_addrtype != AF_INET )
_error("'%s' isn't an Internet site, or so the DNS says",host_name);
address = *(unsigned long *)(host_ptr->h_addr);
}
// Read from the socket returning the
// size of the block read
StreamSocket::ReadResult
StreamSocket::read(void * buffer, const unsigned int len)
{
assert( status == Good );
assert( len != 0 );
ReadResult result = { ::read(socket_handle,buffer,len), Good };
if( result.len == 0 )
return result.status = (status = Eof), result;
if( result.len == (unsigned)(-1L) )
if( errno == EWOULDBLOCK )
return result.len = 0, result.status = Nodata, result;
else
{
perror("reading from the socket");
return result.len = 0, result.status = (status = Failure), result;
}
return result;
}
// Set blocking/non-blocking I/O
// If the blocking i/o is set, reading
// on socket blocks the process until
// the packet arrives. If i/o is non-blocking,
// read() returns -1 with errno=EWOULDBLOCK
// if there is nothing to read
void StreamSocket::set_blocking_io(const BOOL onoff)
{
int arg = fcntl(socket_handle,F_GETFL,0);
do_well( arg );
do_well( fcntl(socket_handle,F_SETFL,onoff ? arg & ~FNDELAY :
arg | FNDELAY) );
}
// Enable/disable SIGIO upon arriving of a
// new packet
void StreamSocket::enable_sigio(const BOOL onoff)
{
int arg = fcntl(socket_handle,F_GETFL,0);
do_well( arg );
do_well( fcntl(socket_handle,F_SETFL,onoff ? arg | FASYNC :
arg & ~FASYNC) );
if( onoff ) // Tell which process should get SIGIO
do_well( fcntl(socket_handle,F_SETOWN,getpid()) );
}
//End of File