about summary refs log tree commit diff
path: root/sysdeps/posix/sysconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/posix/sysconf.c')
-rw-r--r--sysdeps/posix/sysconf.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/sysdeps/posix/sysconf.c b/sysdeps/posix/sysconf.c
index d1286a06fe..de81c2120b 100644
--- a/sysdeps/posix/sysconf.c
+++ b/sysdeps/posix/sysconf.c
@@ -23,14 +23,20 @@
 #include <pwd.h>
 #include <stddef.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <time.h>
 #include <unistd.h>
 #include <sys/param.h>
+#include <sys/stat.h>
 #include <sys/sysinfo.h>
 #include <sys/types.h>
 #include <regex.h>
 
 
+static long int __sysconf_check_spec (const char *spec);
+
+
 /* Get the value of the system variable NAME.  */
 long int
 __sysconf (name)
@@ -781,50 +787,50 @@ __sysconf (name)
 #ifdef _XBS5_ILP32_OFF32
       return _XBS5_ILP32_OFF32;
 #else
-      return -1;
+      return __sysconf_check_spec ("ILP32_OFF32");
 #endif
     case _SC_XBS5_ILP32_OFFBIG:
 #ifdef _XBS5_ILP32_OFFBIG
       return _XBS5_ILP32_OFFBIG;
 #else
-      return -1;
+      return __sysconf_check_spec ("ILP32_OFFBIG");
 #endif
     case _SC_XBS5_LP64_OFF64:
 #ifdef _XBS5_LP64_OFF64
       return _XBS5_LP64_OFF64;
 #else
-      return -1;
+      return __sysconf_check_spec ("LP64_OFF64");
 #endif
     case _SC_XBS5_LPBIG_OFFBIG:
 #ifdef _XBS5_LPBIG_OFFBIG
       return _XBS5_LPBIG_OFFBIG;
 #else
-      return -1;
+      return __sysconf_check_spec ("LPBIG_OFFBIG");
 #endif
 
     case _SC_V6_ILP32_OFF32:
 #ifdef _POSIX_V6_ILP32_OFF32
       return _POSIX_V6_ILP32_OFF32;
 #else
-      return -1;
+      return __sysconf_check_spec ("ILP32_OFF32");
 #endif
     case _SC_V6_ILP32_OFFBIG:
 #ifdef _POSIX_V6_ILP32_OFFBIG
       return _POSIX_V6_ILP32_OFFBIG;
 #else
-      return -1;
+      return __sysconf_check_spec ("ILP32_OFFBIG");
 #endif
     case _SC_V6_LP64_OFF64:
 #ifdef _POSIX_V6_LP64_OFF64
       return _POSIX_V6_LP64_OFF64;
 #else
-      return -1;
+      return __sysconf_check_spec ("LP64_OFF64");
 #endif
     case _SC_V6_LPBIG_OFFBIG:
 #ifdef _POSIX_V6_LPBIG_OFFBIG
       return _POSIX_V6_LPBIG_OFFBIG;
 #else
-      return -1;
+      return __sysconf_check_spec ("LPBIG_OFFBIG");
 #endif
 
     case _SC_XOPEN_LEGACY:
@@ -1189,3 +1195,24 @@ __sysconf (name)
 #undef __sysconf
 weak_alias (__sysconf, sysconf)
 libc_hidden_def (__sysconf)
+
+static long int
+__sysconf_check_spec (const char *spec)
+{
+  int save_errno = errno;
+
+  const char *getconf_dir = __secure_getenv ("GETCONF_DIR") ?: GETCONF_DIR;
+  size_t getconf_dirlen = strlen (getconf_dir);
+  size_t speclen = strlen (spec);
+
+  char name[getconf_dirlen + sizeof ("/_POSIX_V6_") + speclen];
+  memcpy (mempcpy (mempcpy (name, getconf_dir, getconf_dirlen),
+		   "/_POSIX_V6_", sizeof ("/_POSIX_V6_") - 1),
+	  spec, speclen + 1);
+
+  struct stat64 st;
+  long int ret = __xstat64 (_STAT_VER, name, &st) >= 0 ? 1 : -1;
+
+  __set_errno (save_errno);
+  return ret;
+}