SO_ERROR vs. errno

18.7k views Asked by At

For getting socket syscall (like recv) error, which is better (at performance level) ?

  • Use the plain old errno
  • Or use SO_ERROR as getsockopt() optname ?

I think errno (defined to __error() on my system) is faster because it's not a system call. Am I right ?

The advantages of SO_ERROR are : automatic error reset after getting, and we are sure that the error only concerns our socket. It's safer.

Which one do you think is better ? Is there a really difference of performance between the two ?

2

There are 2 answers

6
rob mayoff On BEST ANSWER

Quoting Dan Bernstein:

Situation: You set up a non-blocking socket and do a connect() that returns -1/EINPROGRESS or -1/EWOULDBLOCK. You select() the socket for writability. This returns as soon as the connection succeeds or fails. (Exception: Under some old versions of Ultrix, select() wouldn't notice failure before the 75-second timeout.)

Question: What do you do after select() returns writability? Did the connection fail? If so, how did it fail?

If the connection failed, the reason is hidden away inside something called so_error in the socket. Modern systems let you see so_error with getsockopt(,,SO_ERROR,,) ...

He goes on to discuss the fact that getsockopt(,,SO_ERROR,,) is a modern invention that doesn't work on old systems, and how to get the error code on such systems. But you probably don't need to worry about that if you're programming for a Unix/Linux system released in the last 15 years.

The Linux man page for connect describes the same usage of SO_ERROR.

So, if you're performing asynchronous operations on sockets, you may need to use SO_ERROR. In any other case, just use errno.

0
Vincent Xue On

Quoting Unix Network Programming:

If so_error is nonzero when the process calls read and there is no data to return, read returns –1 with errno set to the value of so_error (p. 516 of TCPv2). The value of so_error is then reset to 0. If there is data queued for the socket, that data is returned by read instead of the error condition. If so_error is nonzero when the process calls write, –1 is returned with errno set to the value of so_error (p. 495 of TCPv2) and so_error is reset to 0.

So, errno is the better choice, unless you want to get error immediately before the data is fully fetched.