SO_ERROR vs. errno

Félix Faisant picture Félix Faisant · Jan 9, 2014 · Viewed 13.8k times · Source

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 ?

Answer

rob mayoff picture rob mayoff · Jan 9, 2014

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.