10

I'm doing some socket programming in Linux and am wondering how to get the error code when the function socket(...); fails.

for example for the "getaddrinfo" function i can do this:

//Resolve the server address and port
    result = (struct addrinfo *) calloc(1, sizeof(struct addrinfo));
    iResult = getaddrinfo("google.com", DEFAULT_PORT, &hints, &result);
    if (iResult != 0){
        printf("%d\n", iResult);
        fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(iResult));
        getchar();
        exit(EXIT_FAILURE);
    }

However I want to do a similar thing using socket(...) function.

According to this: http://linux.die.net/man/2/socket

the function returns -1 on failure, and sets errno to the appropriate error number. How do i access this "errno" though? This is my code so far:

int connectSocket = 0;
connectSocket = socket(AF_INET, SOCK_STREAM, 0);
printf("%d\n", connectSocket);

if (connectSocket == -1){
    printf("socket failed with error: %s\n", error_string); //TODO: HELP DECLARING error_string
    getchar();
    exit(EXIT_FAILURE);
}
2
  • 2
    See errno(3) and strerror(3) manual pages. Commented Nov 24, 2014 at 2:28
  • 2
    DO NOT allocate memory for the addrinfo that you pass in the last parameter of getaddrinfo(). It will allocate the addrinfo for you, which you pass to freeaddrinfo() to free it: result = NULL; iResult = getaddrinfo(..., &result); if (iResult == 0) { ...; freeaddrinfo(result); } Commented Nov 24, 2014 at 6:29

2 Answers 2

19

errno is a thread-local global variable, defined in <errno.h>. The man page for many library functions will indicate that they return -1 on error, and set errno.

You can convert an errno value to a useful string with the strerror function.

In general, you should code like this:

#include <stdio.h>
#include <errno.h>

int main(void) {
    int s;

    s = socket(...);
    if (s < 0) {
        fprintf(stderr, "socket() failed: %s\n", strerror(errno));
        exit(1);
    }
}

Alternatively, glibc's printf and friends support a %m format specifier, which is replaced with strerror(errno) (no argument is needed). So the above example could be replaced with:

    if (s < 0) {
        fprintf(stderr, "socket() failed: %m\n");
        exit(1);
    }

And to make it all simpler, there is the perror function, which prints out a message similar to above.

    if (s < 0) {
        perror("socket");
        exit(1);
    }

Wrapping it all up - error handling need not be complex and verbose. Putting the socket call and the test for < 0 in one statement, the above code could look like this, and you'll be a real UNIX pro:

#include <stdio.h>
#include <errno.h>

int main(void) {
    int s;

    if ((s = socket(...)) < 0) {
        perror("socket");
        exit(1);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Oddly enough: "fprintf(stderr, "socket() failed: %s\n", strerror(errno));" didn't seem to work! Instead it would just exit the program. But all the rest did! Many Thanks!
nit: #define errno (*__get_errno()) would be legal, it's not necessarily a variable, it's a macro "which expands to a modifiable lvalue that has type int and thread local storage".
5

Add #include <errno.h> and you'll be able to read the global errno variable.

connectSocket = socket(AF_INET, SOCK_STREAM, 0);
if (connectSocket < 0) {
    if (errno == EACCESS) ...

You can use perror in stdio.h to print an error message based on the value of errno or you can use strerror in string.h to access a string describing the error code

connectSocket = socket(AF_INET, SOCK_STREAM, 0);
if (connectSocket < 0) {
    perror("socket");
    exit(EXIT_FAILURE);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.