10

I'm fixing some Linux code which used strerror (not thread-safe) for multi-threading. I found that strerror_r and strerror_l are both thread-safe. Due to different definitions for strerror_r (depending on _GNU_SOURCE it is differently defined) I'd like to use the newer strerror_l function, but how am I supposed to obtain a locale_t object for the current locale? I'm not using iconv or anything, just plain libc, and I don't see how I can obtain a "default locale" object (I don't care in what language the error is printed, I just want a human readable string.)

Daniel Le
  • 1,800
  • 1
  • 14
  • 23
Anteru
  • 19,042
  • 12
  • 77
  • 121

2 Answers2

3

If you pass "" to the locale parameter newlocale will allocate a locale object set to the current native locale[1]

[1]http://pubs.opengroup.org/onlinepubs/9699919799/functions/newlocale.html

static  locale_t locale;

bool MyStrerrorInit(void)
{
    locale = newlocale(LC_CTYPE_MASK|LC_NUMERIC_MASK|LC_TIME_MASK|LC_COLLATE_MASK|
                       LC_MONETARY_MASK|LC_MESSAGES_MASK,"",(locale_t)0);

    if (locale == (locale_t)0) {
       return false;
    }

    return true;
}

char * MyStrerror(int error)
{
    return strerror_l(error, locale);
}
Will
  • 2,014
  • 2
  • 19
  • 42
clockley1
  • 464
  • 5
  • 16
3

You could use POSIX uselocale:

strerror_l(errno, uselocale((locate_t)0));
Daniel Le
  • 1,800
  • 1
  • 14
  • 23
  • 2
    Well, technically, `NULL` is odd here. It's not `NULL`, it's `(locale_t)0`. `uselocale((locale_t)0)`. Is `locale_t` guaranteed to be a pointer? – KamilCuk Sep 18 '21 at 13:57
  • 1
    @KamilCuk You're right, I mixed `uselocale` up with `setlocale`. I don't think `locale_t` is guaranteed to be a pointer, except that it is in glibc. I've incorporated this into my answer. Thank you. – Daniel Le Sep 18 '21 at 23:16