can't retrieve error through getsockopt while errno = 13

128 Views Asked by At

The following code opens a UDP socket and binds to a privileged port which fails. I want to retrieve the error through getsockopt (SO_ERROR) but I can't. The errno var is 13 but from getsockopt I get 0. I was under the impression getsockopt was the preferred method?


#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <sys/time.h>
#include <errno.h>

int main() {
    int _fd = socket (AF_INET, SOCK_DGRAM,
                       IPPROTO_UDP);

    int on = 1;
    int rc = setsockopt (_fd, SOL_SOCKET, SO_REUSEADDR,
                               reinterpret_cast<char *> (&on), sizeof (on));
    assert(rc == 0);
    struct sockaddr_in server;
    memset(&server, 0, sizeof server);
    server.sin_family = AF_INET; // Use IPv4
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(151); // Bind port
    
    rc = rc | bind (_fd, (struct sockaddr *)&server, sizeof(server));

    int err = -1;
    socklen_t len = sizeof err;
    int rc2 = getsockopt (_fd, SOL_SOCKET, SO_ERROR, &err, &len);
    printf("end rc=%i rc2=%i err=%i errno=%i : %m\n", rc, rc2, err, errno);
    sleep(10);
}
1

There are 1 best solutions below

0
On

I think you misunderstand what SO_ERROR is for. It's not a substitute for errno - that has already told you why the call to bind failed.

Instead, it is meant to be used for established connections that might encounter an error condition which cannot be reported immediately (such as an asychronous operation on a non-blocking socket). There's a better description than the rather bare-bones man page here:

https://www.ibm.com/docs/en/zvse/6.2?topic=SSB27H_6.2.0/fa2ti_call_getsockopt.htm