Félix Faisant Félix Faisant - 3 months ago 12
C Question

SO_ERROR vs. errno

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

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.