If $LANG is any available locale other than C or POSIX, If /usr/lib/locale/locale-archive does not exist setlocale is setting errno to ENOENT. If locale data are stored in /usr/lib/locale/<locale_name>/LC_* files, then /usr/lib/locale/locale-archive is not needed and errno must not be set. Try to compile and run the code below: // slt.c #include <errno.h> #include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main () { char *c = setlocale (LC_NUMERIC, ""); fprintf (stderr, "errno = %s\n", strerror (errno)); fprintf (stderr, "setlocale (LC_NUMERIC, \"\") returned %s\n", c); return 0; } // The C code ended. Example: pedro@ubuntu:~/programming/c/setlocale problem$ ./slt.Ubuntu64 errno = Success setlocale (LC_NUMERIC, "") returned pt_BR.utf8 pedro@ubuntu:~/programming/c/setlocale problem$ sudo mv /usr/lib/locale/locale-archive /usr/lib/locale/locale-archive.valid [sudo] password for pedro: pedro@ubuntu:~/programming/c/setlocale problem$ ./slt.Ubuntu64 errno = No such file or directory setlocale (LC_NUMERIC, "") returned pt_BR.utf8
errno is allowed to be modified except in very few exception cases. setlocale is not among them. The caller must not look at errno unless the call fails.