Search code examples
cc99errno

Why can't I save the numeric value of errno?


I tried to save the value of errno for later evaluation, but failed:

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

void main(void)
{

  int read_errno;

  /* read() operation sets errno */
  read(...);
  read_errno = errno;
  printf("errno was %s\n", strerror(errno));
  printf("errno was %s\n", strerror(read_errno));
}

Here the results was:

errno was Stream ioctl timeout
errno was Success

Why can't I save the numeric value of errno to the variable read_errno?


Solution

  • The call to printf or possibly strerror itself reset* the errno variable so the second printf prints the result of the first one, not read. Good practice is to save it as soon as possible, before any other function call.

    Correct example:

    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    
    int main(){
        errno=EPERM; // An example
        int read_errno = errno;
        printf("errno was %s\n", strerror(read_errno));
        printf("errno was %s\n", strerror(read_errno));
    }
    

    Output:

    errno was Operation not permitted
    errno was Operation not permitted
    

    *They do not have to reset it, furthermore successfull call to strerror must not modify it.