(root)/
glibc-2.38/
posix/
confstr.c
       1  /* Copyright (C) 1991-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <stddef.h>
      19  #include <errno.h>
      20  #include <unistd.h>
      21  #include <string.h>
      22  #include <confstr.h>
      23  #include "../version.h"
      24  
      25  #define NEED_SPEC_ARRAY 0
      26  #include <posix-conf-vars.h>
      27  
      28  /* If BUF is not NULL and LEN > 0, fill in at most LEN - 1 bytes
      29     of BUF with the value corresponding to NAME and zero-terminate BUF.
      30     Return the number of bytes required to hold NAME's entire value.  */
      31  size_t
      32  __confstr (int name, char *buf, size_t len)
      33  {
      34    const char *string = "";
      35    size_t string_len = 1;
      36  
      37    /* Note that this buffer must be large enough for the longest strings
      38       used below.  */
      39    char restenvs[4 * sizeof "POSIX_V7_LPBIG_OFFBIG"];
      40  
      41    switch (name)
      42      {
      43      case _CS_PATH:
      44        {
      45  	static const char cs_path[] = CS_PATH;
      46  	string = cs_path;
      47  	string_len = sizeof (cs_path);
      48        }
      49        break;
      50  
      51        /* For _CS_V7_WIDTH_RESTRICTED_ENVS, _CS_V6_WIDTH_RESTRICTED_ENVS
      52  	 and _CS_V5_WIDTH_RESTRICTED_ENVS:
      53  
      54  	 We have to return a newline-separated list of names of
      55  	 programming environments in which the widths of blksize_t,
      56  	 cc_t, mode_t, nfds_t, pid_t, ptrdiff_t, size_t, speed_t,
      57  	 ssize_t, suseconds_t, tcflag_t, useconds_t, wchar_t, and
      58  	 wint_t types are no greater than the width of type long.
      59  
      60  	 Currently this means all environments that the system allows.  */
      61  
      62  #define START_ENV_GROUP(VERSION)		\
      63      case _CS_##VERSION##_WIDTH_RESTRICTED_ENVS:	\
      64        string_len = 0;
      65  
      66  #define END_ENV_GROUP(VERSION)			\
      67        restenvs[string_len++] = '\0';		\
      68        string = restenvs;			\
      69        break;
      70  
      71  #define KNOWN_ABSENT_ENVIRONMENT(SC_PREFIX, ENV_PREFIX, SUFFIX)	\
      72        /* Empty.  */
      73  
      74  #define KNOWN_PRESENT_ENV_STRING(STR)		\
      75        if (string_len > 0)			\
      76  	restenvs[string_len++] = '\n';		\
      77        memcpy (restenvs + string_len, STR,	\
      78  	      sizeof STR - 1);			\
      79        string_len += sizeof STR - 1;
      80  
      81  #define KNOWN_PRESENT_ENVIRONMENT(SC_PREFIX, ENV_PREFIX, SUFFIX)	\
      82        KNOWN_PRESENT_ENV_STRING (#ENV_PREFIX "_" #SUFFIX)
      83  
      84  #define UNKNOWN_ENVIRONMENT(SC_PREFIX, ENV_PREFIX, SUFFIX)		\
      85        if (__sysconf (_SC_##SC_PREFIX##_##SUFFIX) > 0)			\
      86  	{								\
      87  	  KNOWN_PRESENT_ENVIRONMENT (SC_PREFIX, ENV_PREFIX, SUFFIX)	\
      88  	}
      89  
      90  #include "posix-envs.def"
      91  
      92  #undef START_ENV_GROUP
      93  #undef END_ENV_GROUP
      94  #undef KNOWN_ABSENT_ENVIRONMENT
      95  #undef KNOWN_PRESENT_ENV_STRING
      96  #undef KNOWN_PRESENT_ENVIRONMENT
      97  #undef UNKNOWN_ENVIRONMENT
      98  
      99      case _CS_XBS5_ILP32_OFF32_CFLAGS:
     100      case _CS_POSIX_V6_ILP32_OFF32_CFLAGS:
     101      case _CS_POSIX_V7_ILP32_OFF32_CFLAGS:
     102  #ifdef __ILP32_OFF32_CFLAGS
     103  # if CONF_IS_DEFINED_UNSET (_POSIX_V7_ILP32_OFF32)
     104  #  error "__ILP32_OFF32_CFLAGS should not be defined"
     105  # elif CONF_IS_UNDEFINED (_POSIX_V7_ILP32_OFF32)
     106        if (__sysconf (_SC_V7_ILP32_OFF32) < 0)
     107  	break;
     108  # endif
     109        string = __ILP32_OFF32_CFLAGS;
     110        string_len = sizeof (__ILP32_OFF32_CFLAGS);
     111  #endif
     112        break;
     113  
     114      case _CS_XBS5_ILP32_OFFBIG_CFLAGS:
     115      case _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS:
     116      case _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS:
     117  #ifdef __ILP32_OFFBIG_CFLAGS
     118  # if CONF_IS_DEFINED_UNSET (_POSIX_V7_ILP32_OFFBIG)
     119  #  error "__ILP32_OFFBIG_CFLAGS should not be defined"
     120  # elif CONF_IS_UNDEFINED (_POSIX_V7_ILP32_OFFBIG)
     121        if (__sysconf (_SC_V7_ILP32_OFFBIG) < 0)
     122  	break;
     123  # endif
     124        string = __ILP32_OFFBIG_CFLAGS;
     125        string_len = sizeof (__ILP32_OFFBIG_CFLAGS);
     126  #endif
     127        break;
     128  
     129      case _CS_XBS5_LP64_OFF64_CFLAGS:
     130      case _CS_POSIX_V6_LP64_OFF64_CFLAGS:
     131      case _CS_POSIX_V7_LP64_OFF64_CFLAGS:
     132  #ifdef __LP64_OFF64_CFLAGS
     133  # if CONF_IS_DEFINED_UNSET (_POSIX_V7_LP64_OFF64)
     134  #  error "__LP64_OFF64_CFLAGS should not be defined"
     135  # elif CONF_IS_UNDEFINED (_POSIX_V7_LP64_OFF64)
     136        if (__sysconf (_SC_V7_LP64_OFF64) < 0)
     137  	break;
     138  # endif
     139        string = __LP64_OFF64_CFLAGS;
     140        string_len = sizeof (__LP64_OFF64_CFLAGS);
     141  #endif
     142        break;
     143  
     144      case _CS_XBS5_ILP32_OFF32_LDFLAGS:
     145      case _CS_POSIX_V6_ILP32_OFF32_LDFLAGS:
     146      case _CS_POSIX_V7_ILP32_OFF32_LDFLAGS:
     147  #ifdef __ILP32_OFF32_LDFLAGS
     148  # if CONF_IS_DEFINED_UNSET (_POSIX_V7_ILP32_OFF32 )
     149  #  error "__ILP32_OFF32_LDFLAGS should not be defined"
     150  # elif CONF_IS_UNDEFINED (_POSIX_V7_ILP32_OFF32)
     151        if (__sysconf (_SC_V7_ILP32_OFF32) < 0)
     152  	break;
     153  # endif
     154        string = __ILP32_OFF32_LDFLAGS;
     155        string_len = sizeof (__ILP32_OFF32_LDFLAGS);
     156  #endif
     157        break;
     158  
     159      case _CS_XBS5_ILP32_OFFBIG_LDFLAGS:
     160      case _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS:
     161      case _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS:
     162  #ifdef __ILP32_OFFBIG_LDFLAGS
     163  # if CONF_IS_DEFINED_UNSET (_POSIX_V7_ILP32_OFFBIG)
     164  #  error "__ILP32_OFFBIG_LDFLAGS should not be defined"
     165  # elif CONF_IS_UNDEFINED (_POSIX_V7_ILP32_OFFBIG)
     166        if (__sysconf (_SC_V7_ILP32_OFFBIG) < 0)
     167  	break;
     168  # endif
     169        string = __ILP32_OFFBIG_LDFLAGS;
     170        string_len = sizeof (__ILP32_OFFBIG_LDFLAGS);
     171  #endif
     172        break;
     173  
     174      case _CS_XBS5_LP64_OFF64_LDFLAGS:
     175      case _CS_POSIX_V6_LP64_OFF64_LDFLAGS:
     176      case _CS_POSIX_V7_LP64_OFF64_LDFLAGS:
     177  #ifdef __LP64_OFF64_LDFLAGS
     178  # if CONF_IS_DEFINED_UNSET (_POSIX_V7_LP64_OFF64)
     179  #  error "__LP64_OFF64_LDFLAGS should not be defined"
     180  # elif CONF_IS_UNDEFINED (_POSIX_V7_LP64_OFF64)
     181        if (__sysconf (_SC_V7_LP64_OFF64) < 0)
     182  	break;
     183  # endif
     184        string = __LP64_OFF64_LDFLAGS;
     185        string_len = sizeof (__LP64_OFF64_LDFLAGS);
     186  #endif
     187        break;
     188  
     189      case _CS_LFS_CFLAGS:
     190      case _CS_LFS_LINTFLAGS:
     191  #if (CONF_IS_DEFINED_SET (_POSIX_V6_ILP32_OFF32) \
     192       && CONF_IS_DEFINED_SET (_POSIX_V6_ILP32_OFFBIG))
     193  # define __LFS_CFLAGS "-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
     194        /* Signal that we want the new ABI.  */
     195        string = __LFS_CFLAGS;
     196        string_len = sizeof (__LFS_CFLAGS);
     197  #endif
     198        break;
     199  
     200      case _CS_LFS_LDFLAGS:
     201      case _CS_LFS_LIBS:
     202        /* No special libraries or linker flags needed.  */
     203        break;
     204  
     205      case _CS_LFS64_CFLAGS:
     206      case _CS_LFS64_LINTFLAGS:
     207  #define __LFS64_CFLAGS "-D_LARGEFILE64_SOURCE"
     208        string = __LFS64_CFLAGS;
     209        string_len = sizeof (__LFS64_CFLAGS);
     210        break;
     211  
     212      case _CS_LFS64_LDFLAGS:
     213      case _CS_LFS64_LIBS:
     214        /* No special libraries or linker flags needed.  */
     215        break;
     216  
     217      case _CS_XBS5_ILP32_OFF32_LIBS:
     218      case _CS_XBS5_ILP32_OFF32_LINTFLAGS:
     219      case _CS_XBS5_ILP32_OFFBIG_LIBS:
     220      case _CS_XBS5_ILP32_OFFBIG_LINTFLAGS:
     221      case _CS_XBS5_LP64_OFF64_LIBS:
     222      case _CS_XBS5_LP64_OFF64_LINTFLAGS:
     223      case _CS_XBS5_LPBIG_OFFBIG_CFLAGS:
     224      case _CS_XBS5_LPBIG_OFFBIG_LDFLAGS:
     225      case _CS_XBS5_LPBIG_OFFBIG_LIBS:
     226      case _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS:
     227  
     228      case _CS_POSIX_V6_ILP32_OFF32_LIBS:
     229      case _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS:
     230      case _CS_POSIX_V6_ILP32_OFFBIG_LIBS:
     231      case _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS:
     232      case _CS_POSIX_V6_LP64_OFF64_LIBS:
     233      case _CS_POSIX_V6_LP64_OFF64_LINTFLAGS:
     234      case _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS:
     235      case _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS:
     236      case _CS_POSIX_V6_LPBIG_OFFBIG_LIBS:
     237      case _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS:
     238  
     239      case _CS_POSIX_V7_ILP32_OFF32_LIBS:
     240      case _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS:
     241      case _CS_POSIX_V7_ILP32_OFFBIG_LIBS:
     242      case _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS:
     243      case _CS_POSIX_V7_LP64_OFF64_LIBS:
     244      case _CS_POSIX_V7_LP64_OFF64_LINTFLAGS:
     245      case _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS:
     246      case _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS:
     247      case _CS_POSIX_V7_LPBIG_OFFBIG_LIBS:
     248      case _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS:
     249        /* GNU libc does not require special actions to use LFS functions.  */
     250        break;
     251  
     252      case _CS_GNU_LIBC_VERSION:
     253        string = "glibc " VERSION;
     254        string_len = sizeof ("glibc " VERSION);
     255        break;
     256  
     257      case _CS_GNU_LIBPTHREAD_VERSION:
     258  #ifdef LIBPTHREAD_VERSION
     259        string = LIBPTHREAD_VERSION;
     260        string_len = sizeof LIBPTHREAD_VERSION;
     261        break;
     262  #else
     263        /* No thread library.  */
     264        __set_errno (EINVAL);
     265        return 0;
     266  #endif
     267  
     268      case _CS_V6_ENV:
     269      case _CS_V7_ENV:
     270        /* Maybe something else is needed in future.  */
     271        string = "POSIXLY_CORRECT=1";
     272        string_len = sizeof ("POSIXLY_CORRECT=1");
     273        break;
     274  
     275      default:
     276        __set_errno (EINVAL);
     277        return 0;
     278      }
     279  
     280    if (len > 0 && buf != NULL)
     281      {
     282        if (string_len <= len)
     283  	memcpy (buf, string, string_len);
     284        else
     285  	{
     286  	  memcpy (buf, string, len - 1);
     287  	  buf[len - 1] = '\0';
     288  	}
     289      }
     290    return string_len;
     291  }
     292  libc_hidden_def (__confstr)
     293  libc_hidden_def (confstr)
     294  weak_alias (__confstr, confstr)