Search code examples
cerror-handlingpthreadsstrerror

Example of strerror_r


I'm a newbie in error handling; in my code I need to test the returned value of a function and to print the error's description if an error happens.

In order to keep the code thread-safe I have to use strerror_r, but I have some difficult to use it. In the following code the error number 22 happens (ret_setschedparam is 22). How can I print the description of the error number 22, i.e. "Invalid argument", by using the strerror_r?

I think that this prototype should be the right strerror_r I need:

char *strerror_r(int errnum, char *buf, size_t buflen);

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <errno.h>
#include <string.h>

void *task();

int main()
{
pthread_attr_t attr;
struct sched_param prio;
pthread_t tid;
int ret_create;
int ret_setschedparam;
int ret_getschedparam;
int ret_join;
char *buf_setschedparam;
size_t size_setschedparam = 1024;



 pthread_attr_init(&attr);

 prio.sched_priority = 12;
 ret_setschedparam = pthread_attr_setschedparam(&attr, &prio);
 if (ret_setschedparam != 0) {
  printf("Errore numero (pthread_attr_setschedparam): %s\n", strerror_r(errno, buf_setschedparam, size_setschedparam));
  exit(EXIT_FAILURE);
  }
    
 ret_create = pthread_create(&tid, &attr, task, NULL);
 printf("%d %d\n", ret_create, EPERM);
 if (ret_create != 0) {
  printf("Errore numero (pthread_create): %d\n", ret_create);

  exit(EXIT_FAILURE);
  }

 ret_getschedparam = pthread_attr_getschedparam(&attr, &prio);
 if (ret_getschedparam != 0) {
  printf("Errore numero (pthread_attr_getschedparam): %d\n", ret_getschedparam);
  exit(EXIT_FAILURE);
  }

 printf("Livello di priorità del thread: %d\n", prio.sched_priority);

 ret_join = pthread_join(tid, NULL);
 if (ret_join != 0) {
  printf("Errore numero (pthread_join): %d\n", ret_join);
  exit(EXIT_FAILURE);
  }

 return(0);
}


void *task()
{
 printf("I am a simple thread.\n");
 pthread_exit(NULL);
}

The compiler gives me an error: it said that the output of strerror_r is an int, not a char.


Solution

  • I think that this prototype should be the right strerro_r I need:

    Note that this isn't the standard strerror_r interface, but a GNU extension.

    You probably want to build your program with -D_GNU_SOURCE or add #define _GNU_SOURCE 1 to the top of your file to get this prototype instead of the standard one.

    You are also not calling strerror_r correctly. This call:

    char *buf_setschedparam;
    size_t size_setschedparam = 1024;
    
    ... strerror_r(errno, buf_setschedparam, size_setschedparam)
    

    promises to strerror_r that buf_setscheparam points to a buffer of size 1024. In fact that pointer is uninitialized, so once you get your program to build, it will promptly crash.

    In addition, pthread_* functions do not set errno, they return the error code directly.

    You want:

    const size_t size_setschedparam = 1024;
    char buf_setschedparam[size_setschedparam];
    
    ... sterror_r(ret_setschedparam, buf_setschedparam, size_setschedparam);
    

    or even better:

    char buf[1024];
    
       ... sterror_r(ret_setschedparam, buf, sizeof(buf));