Reputation: 956
Today, I was making small changes to my Linux code. The code is a kind of ping-pong network program. The client writes "Hello", the server responds with "Hello". That is all to it.
Now I use FreeBSD. So naturally epoll
mechanism being replaced by kqueue
.
The part of code that did a connect
had caught my attention. The below is trimmed down code
to show how I do non-blocking connect
with Linux.
n = epoll_wait (ep_fd, ep_evs, YPOLL_EPOLL_NEVENTS, timeout_ms);
/* check epoll return for errors */
/* ... */
for(i = 0; i < n; ++i) { /* service epoll events */
sock = (sock*)ep_evs[i].data.ptr; /* user data */
state = sock->state; /* store socket state: paired, connecting, closed, listening */
mask = ep_evs[i].events;
/* connection in progress may have errors at the very start */
if(state != CONNECTION_IN_PROGRESS){
if(mask & EPOLLHUP){ /* hang up, both read/write not possible */
/* do something */
continue; /* next event */
}
if(mask & EPOLLERR) { /* error, or pipe read end has been closed */
/* do something */
continue; /* next event */
}
}
/* test for various events */
/* ... */
/* fd is a socket that is yet to be connected */
else if((state == CONNECTION_IN_PROGRESS) && (mask & EPOLLOUT)) {
int v = /* call getsockopt for `SO_ERROR` */
if(v != 0){ /* connection failed */
/* do something, maybe print error */
continue; /* next event */
}
/* connection passed */
/* maybe add the socket to the list of connected sockets ? */
continue; /* next event */
}
}
The above works for me to do a non-blocking connect to a server. With Linux.
And here I get closer to the question part. The kqueue
interface has flags
and fflags
set for the event.
The plan is to do the same with FreeBSD, so that code will do a non-blocking connect.
Do I have to call getsockopt
to test for the error,
or I would better check for an error with flags
and fflags
?
Update
I see that the question somewhat unclear in wording. I rephrase and explain. With Linux, the only way, for me, to catch an error with a non-blocking connect, - is to call getsockopt
, getting SO_ERROR
. Tests for epoll masks, like EPOLLHUP
, does not catch all errors. The code with getsockopt
, is the only option for me. I had tested various setups, and the check with SO_ERROR
does cover some error paths that epoll error reporting does not. Again, I have to admit, that the above is for my system, with my network setup, etc.
My question is, will kqueue
set EOF
and fflags
in case of an error with non-blocking connect? And preferably, can I safely assume that testing for EOF
will cover all error cases?
Update
Since the last write up, I've tested some code paths of an error with a non-blocking connection. The flags are set for the following: TIMEDOUT
, CONNRESET
, CONNREFUSED
. I can not test all possible code paths, so I just settle for testing EV_EOF
, for now.
Upvotes: 0
Views: 281