Bug 195955

Summary: sysconf(_SC_NPROCESSORS_ONLN) errno can be set to non-zerro on success
Product: Documentation Reporter: Pavel Tikhomirov (ptikhomirov)
Component: man-pagesAssignee: documentation_man-pages (documentation_man-pages)
Status: RESOLVED CODE_FIX    
Severity: normal CC: mtk.manpages
Priority: P1    
Hardware: All   
OS: Linux   
URL: https://sourceware.org/bugzilla/show_bug.cgi?id=21536
Kernel Version: Subsystem:
Regression: No Bisected commit-id:

Description Pavel Tikhomirov 2017-06-01 11:29:18 UTC
http://man7.org/linux/man-pages/man3/sysconf.3.html says:

"If name is invalid, -1 is returned, and errno is set to EINVAL. Otherwise, the value returned is the value of the system resource and errno is not changed."

Which I understand as if successful the call to sysconf() should not change errno.

But if on your system there is no /sys/devices/system/cpu/online (which for instance can happen in container), you will get errno=ENOENT(2) running these simple test, while the call is successful (nrproconln != -1):

/# cat sysconf_nrproc_onln.c 
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

int main()
{
        long nrproconln;

        printf("Before: errno=%d\n", errno);
        nrproconln = sysconf(_SC_NPROCESSORS_ONLN);
        printf("After: nrproc_onln=%ld errno=%d\n", nrproconln, errno);

        return 0;
}

/# gcc -o sysconf_nrproc_onln sysconf_nrproc_onln.c 
/# ./sysconf_nrproc_onln 
Before: errno=0
After: nrproc_onln=4 errno=2

Glibc people say that it is OK, and according to POSIX errno is undefined in case of succesfull call:
https://sourceware.org/bugzilla/show_bug.cgi?id=21536

So we need to change man to say that in case of success errno is undefined.
Comment 1 Michael Kerrisk 2017-06-17 08:58:08 UTC
Yes, this looks like a very longstanding bug in the man page. That text is in general rather hard to parse, and I've rewritten it as below.

Cheers,

Michael

    RETURN VALUE
       The return value of sysconf() is one of the following:

       *  On error, -1 is returned and errno is set to indicate the cause
          of  the  error  (for  example,  EINVAL, indicating that name is
          invalid).

       *  If name corresponds to a maximum or  minimum  limit,  and  that
          limit  is  indeterminate,  -1  is  returned  and  errno  is not
          changed.  (To distinguish an indeterminate limit from an error,
          set errno to zero before the call, and then check whether errno
          is nonzero when -1 is returned.)

       *  If name corresponds to an option, -1 is returned if the  option
          is not supported.

       *  Otherwise,  the  current  value  of  the  option  or  limit  is
          returned.  This value will not be  more  restrictive  than  the
          corresponding  value  that  was described to the application in
          <unistd.h> or <limits.h> when the application was compiled.