Hey thank you nkhambal. I tried to setting the socket to NONBLOCKING. I scanned these IPs:
216.248.62.200 to 216.248.62.204
They all had the same errors (EAGAIN), yet when I switched back to BLOCKING (because I just used NONBLOCKING for validation to see if there is something to read), 216.248.62.204 froze...because it passed as a valid NONBLOCKING source.
I don't know what to do :[
Code:
// Make sure the socket has something to read by validating it with NONBLOCKING capabilites
static Bool check_read(int fd,char *buf, int len, struct timeval *timeout, int *err)
{
int saveflags,ret,back_err;
unsigned int ulen;
fd_set fd_w;
/* Save flags from socket */
saveflags=fcntl(fd,F_GETFL,0);
if(saveflags<0) { comment( "fcntl1" ); *err = errno; return FALSE; }
puts( "Check 1" );
/* Set socket to nonblocking */
if(fcntl(fd,F_SETFL,saveflags|O_NONBLOCK)<0) { comment("fcntl2"); *err=errno; return FALSE; }
puts( "Check 2" );
/* Nonblocking returns immediately */
*err=read(fd, buf, len);
back_err=errno;
puts( "Check 3" );
/* Restore flags */
if(fcntl(fd,F_SETFL,saveflags)<0) { comment("fcntl3"); *err=errno; return FALSE; }
puts( "Check 4" );
printf( "back_err: %ld\n*err: %ld\n", ( long )back_err, (long)*err );
if( back_err != EAGAIN )
return FALSE;
/* Keep going unless the connection was a failure AND not in progress
if(*err<0 && back_err!=EINPROGRESS) { comment("connect"); *err=errno; return FALSE; }*/
FD_ZERO( &fd_w );
FD_SET( fd, &fd_w );
puts( "Check 5" );
/* Select... */
*err = select( FD_SETSIZE, NULL, &fd_w, NULL, timeout );
if(*err<0) { comment("select"); *err=errno; return FALSE; }
puts( "Check 6" );
/* 0 means it timeout out & no fds changed */
if(*err==0) { close(fd); *err=ETIMEDOUT; return FALSE; }
puts( "Check 7" );
/* Get the return code from the connect */
len=sizeof(ret);
ulen = (unsigned int) len;
*err=getsockopt(fd,SOL_SOCKET,SO_ERROR,&ret,&ulen);
if(*err<0) { comment("getsockopt"); *err=errno; return FALSE; }
puts( "Check 8" );
/* ret=0 means success, otherwise it contains the errno */
if( ret ) { *err=ret; return FALSE; }
puts( "Check 9" );
*err=0;
return TRUE;
}
// Do reading here
static int xread(int fd, char *buf, int len) {
int o=0,l=len,r;
struct timeval to;
int err;
to.tv_sec = 5;
to.tv_usec = 0;
if( !check_read( fd, buf, len, &to, &err ) )
return -1;
memset(buf,0,sizeof buf);
for(;;){
puts( "Reading sentence.." );
r=read(fd, buf+o, l);
puts( "DONE" );
if(r<0){
if(errno==EAGAIN || errno==EINTR)
continue;
else
return -1;
}
if(r==0)
return o;
o+=r;
l-=r;
if(l)
continue;
return len;
}
}