(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
sysconf.c
       1  /* Get file-specific information about a file.  Linux version.
       2     Copyright (C) 2003-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <assert.h>
      20  #include <errno.h>
      21  #include <fcntl.h>
      22  #include <stdlib.h>
      23  #include <sysdep.h>
      24  #include <time.h>
      25  #include <unistd.h>
      26  #include <sys/resource.h>
      27  #include <sys/param.h>
      28  #include <not-cancel.h>
      29  #include <ldsodefs.h>
      30  #include <sysconf-sigstksz.h>
      31  
      32  /* Legacy value of ARG_MAX.  The macro is now not defined since the
      33     actual value varies based on the stack size.  */
      34  #define legacy_ARG_MAX 131072
      35  
      36  /* Newer kernels (4.13) limit the maximum command line arguments lengths to
      37     6MiB.  */
      38  #define maximum_ARG_MAX (6 * 1024 * 1024)
      39  
      40  static long int posix_sysconf (int name);
      41  
      42  
      43  /* Get the value of the system variable NAME.  */
      44  long int
      45  __sysconf (int name)
      46  {
      47    const char *procfname = NULL;
      48  
      49    switch (name)
      50      {
      51      case _SC_MONOTONIC_CLOCK:
      52      case _SC_CPUTIME:
      53      case _SC_THREAD_CPUTIME:
      54        return _POSIX_VERSION;
      55  
      56      case _SC_ARG_MAX:
      57        {
      58          struct rlimit rlimit;
      59          /* Use getrlimit to get the stack limit.  */
      60          if (__getrlimit (RLIMIT_STACK, &rlimit) == 0)
      61  	  {
      62  	    const long int limit = MAX (legacy_ARG_MAX, rlimit.rlim_cur / 4);
      63  	    return MIN (limit, maximum_ARG_MAX);
      64  	  }
      65  
      66          return legacy_ARG_MAX;
      67        }
      68  
      69      case _SC_NGROUPS_MAX:
      70        /* Try to read the information from the /proc/sys/kernel/ngroups_max
      71  	 file.  */
      72        procfname = "/proc/sys/kernel/ngroups_max";
      73        break;
      74  
      75      case _SC_SIGQUEUE_MAX:
      76        {
      77          struct rlimit rlimit;
      78          if (__getrlimit (RLIMIT_SIGPENDING, &rlimit) == 0)
      79  	  return rlimit.rlim_cur;
      80  
      81          /* The /proc/sys/kernel/rtsig-max file contains the answer.  */
      82          procfname = "/proc/sys/kernel/rtsig-max";
      83        }
      84        break;
      85  
      86      case _SC_MINSIGSTKSZ:
      87        assert (GLRO(dl_minsigstacksize) != 0);
      88        return GLRO(dl_minsigstacksize);
      89  
      90      case _SC_SIGSTKSZ:
      91        return sysconf_sigstksz ();
      92  
      93      default:
      94        break;
      95      }
      96  
      97    if (procfname != NULL)
      98      {
      99        int fd = __open_nocancel (procfname, O_RDONLY | O_CLOEXEC);
     100        if (fd != -1)
     101  	{
     102  	  /* This is more than enough, the file contains a single integer.  */
     103  	  char buf[32];
     104  	  ssize_t n;
     105  	  n = TEMP_FAILURE_RETRY (__read_nocancel (fd, buf, sizeof (buf) - 1));
     106  	  __close_nocancel_nostatus (fd);
     107  
     108  	  if (n > 0)
     109  	    {
     110  	      /* Terminate the string.  */
     111  	      buf[n] = '\0';
     112  
     113  	      char *endp;
     114  	      long int res = strtol (buf, &endp, 10);
     115  	      if (endp != buf && (*endp == '\0' || *endp == '\n'))
     116  		return res;
     117  	    }
     118  	}
     119      }
     120  
     121    return posix_sysconf (name);
     122  }
     123  
     124  /* Now the POSIX version.  */
     125  #undef __sysconf
     126  #define __sysconf static posix_sysconf
     127  #include <sysdeps/posix/sysconf.c>