1 /* Copyright (C) 1991,1993,1995-1997,2000
2    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 Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    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    Library General Public License for more details.
14 
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    see <http://www.gnu.org/licenses/>.  */
18 
19 #define _XOPEN_SOURCE  500
20 #include <features.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <limits.h>
24 #include <grp.h>
25 #include <pwd.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <time.h>
30 #include <unistd.h>
31 #include <sys/syscall.h>
32 #include <sys/sysinfo.h>
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #ifdef __UCLIBC_HAS_REGEX__
36 #include <regex.h>
37 #endif
38 #ifdef __UCLIBC_HAS_THREADS_NATIVE__
39 #include <sysdep.h>
40 #endif
41 #include <sys/resource.h>
42 #include <string.h>
43 #include <dirent.h>
44 #include "internal/parse_config.h"
45 
get_phys_pages(void)46 long int get_phys_pages(void)
47 {
48 	struct sysinfo si;
49 	int ps = getpagesize();
50 
51 	sysinfo(&si);
52 
53 	if (ps >= si.mem_unit)
54 		return si.totalram / (ps / si.mem_unit);
55 	else
56 		return si.totalram * (si.mem_unit / ps);
57 }
58 
get_avphys_pages(void)59 long int get_avphys_pages(void)
60 {
61 	struct sysinfo si;
62 	int ps = getpagesize();
63 
64 	sysinfo(&si);
65 
66 	if (ps >= si.mem_unit)
67 		return si.freeram / (ps / si.mem_unit);
68 	else
69 		return si.freeram * (si.mem_unit / ps);
70 }
71 
nprocessors_onln(void)72 static int nprocessors_onln(void)
73 {
74 	char **l = NULL;
75 	parser_t *p = config_open("/proc/stat");
76 	int ret = 0;
77 
78 	if (p) {
79 		while (config_read(p, &l, 2, 1, " ", 0))
80 			if (l[0][0] == 'c'
81 				&& l[0][1] == 'p'
82 				&& l[0][2] == 'u'
83 				&& isdigit(l[0][3]))
84 				++ret;
85 	} else if ((p = config_open("/proc/cpuinfo"))) {
86 #if defined __sparc__
87 		while (config_read(p, &l, 2, 2, "\0:", PARSE_NORMAL))
88 			if (strncmp("ncpus active", l[0], 12) == 0) {
89 				ret = atoi(l[1]);
90 				break;
91 			}
92 #else
93 		while (config_read(p, &l, 2, 2, "\0:\t", PARSE_NORMAL))
94 			if (strcmp("processor", l[0]) == 0)
95 				++ret;
96 #endif
97 	}
98 	config_close(p);
99 	return ret != 0 ? ret : 1;
100 }
101 
nprocessors_conf(void)102 static int nprocessors_conf(void)
103 {
104 	int ret = 0;
105 	DIR *dir = opendir("/sys/devices/system/cpu");
106 
107 	if (dir) {
108 		struct dirent64 *dp;
109 
110 		while ((dp = readdir64(dir))) {
111 			if (dp->d_type == DT_DIR
112 				&& dp->d_name[0] == 'c'
113 				&& dp->d_name[1] == 'p'
114 				&& dp->d_name[2] == 'u'
115 				&& isdigit(dp->d_name[3]))
116 				++ret;
117 		}
118 		closedir(dir);
119 	} else
120 	{
121 #if defined __sparc__
122 		char **l = NULL;
123 		parser_t *p = config_open("/proc/stat");
124 		while (config_read(p, &l, 2, 2, "\0:", PARSE_NORMAL))
125 			if (strncmp("ncpus probed", l[0], 13) == 0) {
126 				ret = atoi(l[1]);
127 				break;
128 			}
129 		config_close(p);
130 #else
131 		ret = nprocessors_onln();
132 #endif
133 	}
134 	return ret != 0 ? ret : 1;
135 }
136 
137 
138 #ifndef __UCLIBC_CLK_TCK_CONST
139 #error __UCLIBC_CLK_TCK_CONST not defined!
140 #endif
141 
142 /***********************************************************************/
143 /*
144  * Manuel Novoa III        Jan 2001
145  *
146  * On i386, the switch-based implementation generates 796 bytes of code.
147  * However, many of the return values are repeats.  By collecting these
148  * repeats and moving to a table-based implementation, we generate 283
149  * bytes on i386 (-Os -fomit-frame-pointer).
150  */
151 
152 #ifdef _UCLIBC_GENERATE_SYSCONF_ARCH
153 /*
154  * Set some errno's so the auto-gen code knows what it is dealing with.
155  *    1) ENOSYS signifies that we're returning a default value.
156  *       This is just extra info for development.
157  *    2) EISNAM signifies that the value returned varies at runtime.
158  *
159  * Option: GETPAGESIZE_IS_DYNAMIC
160  *    The current implementation of getpagesize in uClibc returns
161  *    a constant.  The pagesize on the target arch should not vary,
162  *    so it should be safe to set this as 0.
163  */
164 #define RETURN_NEG_1 __set_errno(ENOSYS); return -1
165 #define RETURN_FUNCTION(f) __set_errno(EISNAM); return (long int) #f
166 #define GETPAGESIZE_IS_DYNAMIC 0
167 #else
168 #define RETURN_NEG_1 return -1
169 #define RETURN_FUNCTION(f) return f;
170 #endif /* _UCLIBC_GENERATE_SYSCONF_ARCH */
171 
172 /* Legacy value of ARG_MAX.  The macro is now not defined since the
173    actual value varies based on the stack size.  */
174 #define legacy_ARG_MAX 131072
175 
176 /* Get the value of the system variable NAME.  */
sysconf(int name)177 long int sysconf(int name)
178 {
179   struct rlimit rlimit;
180 
181   switch (name)
182     {
183     default:
184       __set_errno(EINVAL);
185       return -1;
186 
187     case _SC_ARG_MAX:
188       /* Use getrlimit to get the stack limit.  */
189       if (getrlimit (RLIMIT_STACK, &rlimit) == 0)
190           return MAX (legacy_ARG_MAX, rlimit.rlim_cur / 4);
191 #if defined ARG_MAX
192       return ARG_MAX;
193 #else
194       return legacy_ARG_MAX;
195 #endif
196 
197     case _SC_CHILD_MAX:
198 #ifdef	CHILD_MAX
199       return CHILD_MAX;
200 #else
201       RETURN_NEG_1;
202 #endif
203 
204     case _SC_CLK_TCK:
205       /* Can't use CLK_TCK here since that calls __sysconf(_SC_CLK_TCK) */
206       return __UCLIBC_CLK_TCK_CONST;
207 
208     case _SC_NGROUPS_MAX:
209 #ifdef	NGROUPS_MAX
210       return NGROUPS_MAX;
211 #else
212       RETURN_NEG_1;
213 #endif
214 
215     case _SC_OPEN_MAX:
216       RETURN_FUNCTION(getdtablesize());
217 
218     case _SC_STREAM_MAX:
219 #ifdef	STREAM_MAX
220       return STREAM_MAX;
221 #else
222       return FOPEN_MAX;
223 #endif
224 
225     case _SC_TZNAME_MAX:
226       return _POSIX_TZNAME_MAX;
227 
228     case _SC_JOB_CONTROL:
229 #ifdef	_POSIX_JOB_CONTROL
230       return 1;
231 #else
232       RETURN_NEG_1;
233 #endif
234 
235     case _SC_SAVED_IDS:
236 #ifdef	_POSIX_SAVED_IDS
237       return 1;
238 #else
239       RETURN_NEG_1;
240 #endif
241 
242     case _SC_REALTIME_SIGNALS:
243 #ifdef	_POSIX_REALTIME_SIGNALS
244       return 1;
245 #else
246       RETURN_NEG_1;
247 #endif
248 
249     case _SC_PRIORITY_SCHEDULING:
250 #ifdef	_POSIX_PRIORITY_SCHEDULING
251       return 1;
252 #else
253       RETURN_NEG_1;
254 #endif
255 
256     case _SC_TIMERS:
257 #ifdef	_POSIX_TIMERS
258       return 1;
259 #else
260       RETURN_NEG_1;
261 #endif
262 
263     case _SC_ASYNCHRONOUS_IO:
264 #ifdef	_POSIX_ASYNCHRONOUS_IO
265       return 1;
266 #else
267       RETURN_NEG_1;
268 #endif
269 
270     case _SC_PRIORITIZED_IO:
271 #ifdef	_POSIX_PRIORITIZED_IO
272       return 1;
273 #else
274       RETURN_NEG_1;
275 #endif
276 
277     case _SC_SYNCHRONIZED_IO:
278 #ifdef	_POSIX_SYNCHRONIZED_IO
279       return 1;
280 #else
281       RETURN_NEG_1;
282 #endif
283 
284     case _SC_FSYNC:
285 #ifdef	_POSIX_FSYNC
286       return 1;
287 #else
288       RETURN_NEG_1;
289 #endif
290 
291     case _SC_MAPPED_FILES:
292 #ifdef	_POSIX_MAPPED_FILES
293       return 1;
294 #else
295       RETURN_NEG_1;
296 #endif
297 
298     case _SC_MEMLOCK:
299 #ifdef	_POSIX_MEMLOCK
300       return 1;
301 #else
302       RETURN_NEG_1;
303 #endif
304 
305     case _SC_MEMLOCK_RANGE:
306 #ifdef	_POSIX_MEMLOCK_RANGE
307       return 1;
308 #else
309       RETURN_NEG_1;
310 #endif
311 
312     case _SC_MEMORY_PROTECTION:
313 #ifdef	_POSIX_MEMORY_PROTECTION
314       return 1;
315 #else
316       RETURN_NEG_1;
317 #endif
318 
319     case _SC_MESSAGE_PASSING:
320 #ifdef	_POSIX_MESSAGE_PASSING
321       return 1;
322 #else
323       RETURN_NEG_1;
324 #endif
325 
326     case _SC_SEMAPHORES:
327 #ifdef	_POSIX_SEMAPHORES
328       return 1;
329 #else
330       RETURN_NEG_1;
331 #endif
332 
333     case _SC_SHARED_MEMORY_OBJECTS:
334 #ifdef	_POSIX_SHARED_MEMORY_OBJECTS
335       return 1;
336 #else
337       RETURN_NEG_1;
338 #endif
339 
340     case _SC_VERSION:
341       return _POSIX_VERSION;
342 
343     case _SC_PAGESIZE:
344 #if defined(GETPAGESIZE_IS_DYNAMIC) && (GETPAGESIZE_IS_DYNAMIC == 1)
345       RETURN_FUNCTION(getpagesize());
346 #else
347       return getpagesize();		/* note: currently this is not dynamic */
348 #endif
349 
350     case _SC_AIO_LISTIO_MAX:
351 #ifdef	AIO_LISTIO_MAX
352       return AIO_LISTIO_MAX;
353 #else
354       RETURN_NEG_1;
355 #endif
356 
357     case _SC_AIO_MAX:
358 #ifdef	AIO_MAX
359       return AIO_MAX;
360 #else
361       RETURN_NEG_1;
362 #endif
363 
364     case _SC_AIO_PRIO_DELTA_MAX:
365 #ifdef	AIO_PRIO_DELTA_MAX
366       return AIO_PRIO_DELTA_MAX;
367 #else
368       RETURN_NEG_1;
369 #endif
370 
371     case _SC_DELAYTIMER_MAX:
372 #ifdef	DELAYTIMER_MAX
373       return DELAYTIMER_MAX;
374 #else
375       RETURN_NEG_1;
376 #endif
377 
378     case _SC_MQ_OPEN_MAX:
379 #ifdef	MQ_OPEN_MAX
380       return MQ_OPEN_MAX;
381 #else
382       RETURN_NEG_1;
383 #endif
384 
385     case _SC_MQ_PRIO_MAX:
386 #ifdef	MQ_PRIO_MAX
387       return MQ_PRIO_MAX;
388 #else
389       RETURN_NEG_1;
390 #endif
391 
392     case _SC_RTSIG_MAX:
393 #ifdef	RTSIG_MAX
394       return RTSIG_MAX;
395 #else
396       RETURN_NEG_1;
397 #endif
398 
399     case _SC_SEM_NSEMS_MAX:
400 #ifdef	SEM_NSEMS_MAX
401       return SEM_NSEMS_MAX;
402 #else
403       RETURN_NEG_1;
404 #endif
405 
406     case _SC_SEM_VALUE_MAX:
407 #ifdef	SEM_VALUE_MAX
408       return SEM_VALUE_MAX;
409 #else
410       RETURN_NEG_1;
411 #endif
412 
413     case _SC_SIGQUEUE_MAX:
414 #ifdef	SIGQUEUE_MAX
415       return SIGQUEUE_MAX;
416 #else
417       RETURN_NEG_1;
418 #endif
419 
420     case _SC_TIMER_MAX:
421 #ifdef	TIMER_MAX
422       return TIMER_MAX;
423 #else
424       RETURN_NEG_1;
425 #endif
426 
427     case _SC_BC_BASE_MAX:
428 #ifdef	BC_BASE_MAX
429       return BC_BASE_MAX;
430 #else
431       RETURN_NEG_1;
432 #endif
433 
434     case _SC_BC_DIM_MAX:
435 #ifdef	BC_DIM_MAX
436       return BC_DIM_MAX;
437 #else
438       RETURN_NEG_1;
439 #endif
440 
441     case _SC_BC_SCALE_MAX:
442 #ifdef	BC_SCALE_MAX
443       return BC_SCALE_MAX;
444 #else
445       RETURN_NEG_1;
446 #endif
447 
448     case _SC_BC_STRING_MAX:
449 #ifdef	BC_STRING_MAX
450       return BC_STRING_MAX;
451 #else
452       RETURN_NEG_1;
453 #endif
454 
455     case _SC_COLL_WEIGHTS_MAX:
456 #ifdef	COLL_WEIGHTS_MAX
457       return COLL_WEIGHTS_MAX;
458 #else
459       RETURN_NEG_1;
460 #endif
461 
462     case _SC_EQUIV_CLASS_MAX:
463 #ifdef	EQUIV_CLASS_MAX
464       return EQUIV_CLASS_MAX;
465 #else
466       RETURN_NEG_1;
467 #endif
468 
469     case _SC_EXPR_NEST_MAX:
470 #ifdef	EXPR_NEST_MAX
471       return EXPR_NEST_MAX;
472 #else
473       RETURN_NEG_1;
474 #endif
475 
476     case _SC_LINE_MAX:
477 #ifdef	LINE_MAX
478       return LINE_MAX;
479 #else
480       RETURN_NEG_1;
481 #endif
482 
483     case _SC_RE_DUP_MAX:
484 #ifdef	RE_DUP_MAX
485       return RE_DUP_MAX;
486 #else
487       RETURN_NEG_1;
488 #endif
489 
490     case _SC_CHARCLASS_NAME_MAX:
491 #ifdef	CHARCLASS_NAME_MAX
492       return CHARCLASS_NAME_MAX;
493 #else
494       RETURN_NEG_1;
495 #endif
496 
497     case _SC_PII:
498 #ifdef	_POSIX_PII
499       return 1;
500 #else
501       RETURN_NEG_1;
502 #endif
503 
504     case _SC_PII_XTI:
505 #ifdef	_POSIX_PII_XTI
506       return 1;
507 #else
508       RETURN_NEG_1;
509 #endif
510 
511     case _SC_PII_SOCKET:
512 #ifdef	_POSIX_PII_SOCKET
513       return 1;
514 #else
515       RETURN_NEG_1;
516 #endif
517 
518     case _SC_PII_INTERNET:
519 #ifdef	_POSIX_PII_INTERNET
520       return 1;
521 #else
522       RETURN_NEG_1;
523 #endif
524 
525     case _SC_PII_OSI:
526 #ifdef	_POSIX_PII_OSI
527       return 1;
528 #else
529       RETURN_NEG_1;
530 #endif
531 
532     case _SC_POLL:
533 #ifdef	_POSIX_POLL
534       return 1;
535 #else
536       RETURN_NEG_1;
537 #endif
538 
539     case _SC_SELECT:
540 #ifdef	_POSIX_SELECT
541       return 1;
542 #else
543       RETURN_NEG_1;
544 #endif
545 
546     case _SC_UIO_MAXIOV:
547 #ifdef	UIO_MAXIOV
548       return UIO_MAXIOV;
549 #else
550       RETURN_NEG_1;
551 #endif
552 
553     case _SC_PII_INTERNET_STREAM:
554 #ifdef	_POSIX_PII_INTERNET_STREAM
555       return 1;
556 #else
557       RETURN_NEG_1;
558 #endif
559 
560     case _SC_PII_INTERNET_DGRAM:
561 #ifdef	_POSIX_PII_INTERNET_DGRAM
562       return 1;
563 #else
564       RETURN_NEG_1;
565 #endif
566 
567     case _SC_PII_OSI_COTS:
568 #ifdef	_POSIX_PII_OSI_COTS
569       return 1;
570 #else
571       RETURN_NEG_1;
572 #endif
573 
574     case _SC_PII_OSI_CLTS:
575 #ifdef	_POSIX_PII_OSI_CLTS
576       return 1;
577 #else
578       RETURN_NEG_1;
579 #endif
580 
581     case _SC_PII_OSI_M:
582 #ifdef	_POSIX_PII_OSI_M
583       return 1;
584 #else
585       RETURN_NEG_1;
586 #endif
587 
588     case _SC_T_IOV_MAX:
589 #ifdef	_T_IOV_MAX
590       return _T_IOV_MAX;
591 #else
592       RETURN_NEG_1;
593 #endif
594 
595     case _SC_2_VERSION:
596       return _POSIX2_VERSION;
597 
598     case _SC_2_C_BIND:
599 #ifdef	_POSIX2_C_BIND
600       return _POSIX2_C_BIND;
601 #else
602       RETURN_NEG_1;
603 #endif
604 
605     case _SC_2_C_DEV:
606 #ifdef	_POSIX2_C_DEV
607       return _POSIX2_C_DEV;
608 #else
609       RETURN_NEG_1;
610 #endif
611 
612     case _SC_2_C_VERSION:
613 #ifdef	_POSIX2_C_VERSION
614       return _POSIX2_C_VERSION;
615 #else
616       RETURN_NEG_1;
617 #endif
618 
619     case _SC_2_FORT_DEV:
620 #ifdef	_POSIX2_FORT_DEV
621       return _POSIX2_FORT_DEV;
622 #else
623       RETURN_NEG_1;
624 #endif
625 
626     case _SC_2_FORT_RUN:
627 #ifdef	_POSIX2_FORT_RUN
628       return _POSIX2_FORT_RUN;
629 #else
630       RETURN_NEG_1;
631 #endif
632 
633     case _SC_2_LOCALEDEF:
634 #ifdef	_POSIX2_LOCALEDEF
635       return _POSIX2_LOCALEDEF;
636 #else
637       RETURN_NEG_1;
638 #endif
639 
640     case _SC_2_SW_DEV:
641 #ifdef	_POSIX2_SW_DEV
642       return _POSIX2_SW_DEV;
643 #else
644       RETURN_NEG_1;
645 #endif
646 
647     case _SC_2_CHAR_TERM:
648 #ifdef	_POSIX2_CHAR_TERM
649       return _POSIX2_CHAR_TERM;
650 #else
651       RETURN_NEG_1;
652 #endif
653 
654     case _SC_2_UPE:
655 #ifdef	_POSIX2_UPE
656       return _POSIX2_UPE;
657 #else
658       RETURN_NEG_1;
659 #endif
660 
661       /* POSIX 1003.1c (POSIX Threads).  */
662     case _SC_THREADS:
663 #ifdef __UCLIBC_HAS_THREADS__
664       return 1;
665 #else
666       RETURN_NEG_1;
667 #endif
668 
669     case _SC_THREAD_SAFE_FUNCTIONS:
670 #ifdef __UCLIBC_HAS_THREADS__
671       return 1;
672 #else
673       RETURN_NEG_1;
674 #endif
675 
676 /* If you change these, also change libc/pwd_grp/pwd_grp.c to match */
677     case _SC_GETGR_R_SIZE_MAX:
678       return __UCLIBC_GRP_BUFFER_SIZE__;
679 
680     case _SC_GETPW_R_SIZE_MAX:
681       return __UCLIBC_PWD_BUFFER_SIZE__;
682 
683 /* getlogin() is a worthless interface.  In uClibc we let the user specify
684  * whatever they want via the LOGNAME environment variable, or we return NULL
685  * if getenv() fails to find anything.  So this is merely how large a env
686  * variable can be.  Lets use 256 */
687     case _SC_LOGIN_NAME_MAX:
688       return 256;
689 
690 /* If you change this, also change _SC_TTY_NAME_MAX in libc/unistd/sysconf.c */
691 #define TTYNAME_BUFLEN		32
692     case _SC_TTY_NAME_MAX:
693       return TTYNAME_BUFLEN;
694 
695     case _SC_THREAD_DESTRUCTOR_ITERATIONS:
696 #ifdef	_POSIX_THREAD_DESTRUCTOR_ITERATIONS
697       return _POSIX_THREAD_DESTRUCTOR_ITERATIONS;
698 #else
699       RETURN_NEG_1;
700 #endif
701 
702     case _SC_THREAD_KEYS_MAX:
703 #ifdef	PTHREAD_KEYS_MAX
704       return PTHREAD_KEYS_MAX;
705 #else
706       RETURN_NEG_1;
707 #endif
708 
709     case _SC_THREAD_STACK_MIN:
710 #ifdef	PTHREAD_STACK_MIN
711       return PTHREAD_STACK_MIN;
712 #else
713       RETURN_NEG_1;
714 #endif
715 
716     case _SC_THREAD_THREADS_MAX:
717 #ifdef	PTHREAD_THREADS_MAX
718       return PTHREAD_THREADS_MAX;
719 #else
720       RETURN_NEG_1;
721 #endif
722 
723     case _SC_THREAD_ATTR_STACKADDR:
724 #ifdef	_POSIX_THREAD_ATTR_STACKADDR
725       return 1;
726 #else
727       RETURN_NEG_1;
728 #endif
729 
730     case _SC_THREAD_ATTR_STACKSIZE:
731 #ifdef	_POSIX_THREAD_ATTR_STACKSIZE
732       return 1;
733 #else
734       RETURN_NEG_1;
735 #endif
736 
737     case _SC_THREAD_PRIORITY_SCHEDULING:
738 #ifdef	_POSIX_THREAD_PRIORITY_SCHEDULING
739       return 1;
740 #else
741       RETURN_NEG_1;
742 #endif
743 
744     case _SC_THREAD_PRIO_INHERIT:
745 #ifdef	_POSIX_THREAD_PRIO_INHERIT
746       return 1;
747 #else
748       RETURN_NEG_1;
749 #endif
750 
751     case _SC_THREAD_PRIO_PROTECT:
752 #ifdef	_POSIX_THREAD_PRIO_PROTECT
753       return 1;
754 #else
755       RETURN_NEG_1;
756 #endif
757 
758     case _SC_THREAD_PROCESS_SHARED:
759 #ifdef	_POSIX_THREAD_PROCESS_SHARED
760       return 1;
761 #else
762       RETURN_NEG_1;
763 #endif
764 
765     case _SC_NPROCESSORS_CONF:
766       RETURN_FUNCTION(nprocessors_conf());
767 
768     case _SC_NPROCESSORS_ONLN:
769       RETURN_FUNCTION(nprocessors_onln());
770 
771     case _SC_PHYS_PAGES:
772       RETURN_FUNCTION(get_phys_pages());
773 
774     case _SC_AVPHYS_PAGES:
775       RETURN_FUNCTION(get_avphys_pages());
776 
777     case _SC_ATEXIT_MAX:
778       return __UCLIBC_MAX_ATEXIT;
779 
780     case _SC_PASS_MAX:
781       /* We have no limit but since the return value might be used to
782 	 allocate a buffer we restrict the value.  */
783       return BUFSIZ;
784 
785     case _SC_XOPEN_VERSION:
786       return _XOPEN_VERSION;
787 
788     case _SC_XOPEN_XCU_VERSION:
789       return _XOPEN_XCU_VERSION;
790 
791     case _SC_XOPEN_UNIX:
792       return _XOPEN_UNIX;
793 
794     case _SC_XOPEN_CRYPT:
795 #ifdef	_XOPEN_CRYPT
796       return _XOPEN_CRYPT;
797 #else
798       RETURN_NEG_1;
799 #endif
800 
801     case _SC_XOPEN_ENH_I18N:
802 #ifdef	_XOPEN_ENH_I18N
803       return _XOPEN_ENH_I18N;
804 #else
805       RETURN_NEG_1;
806 #endif
807 
808     case _SC_XOPEN_SHM:
809 #ifdef	_XOPEN_SHM
810       return _XOPEN_SHM;
811 #else
812       RETURN_NEG_1;
813 #endif
814 
815     case _SC_XOPEN_XPG2:
816 #ifdef	_XOPEN_XPG2
817       return _XOPEN_XPG2;
818 #else
819       RETURN_NEG_1;
820 #endif
821 
822     case _SC_XOPEN_XPG3:
823 #ifdef	_XOPEN_XPG3
824       return _XOPEN_XPG3;
825 #else
826       RETURN_NEG_1;
827 #endif
828 
829     case _SC_XOPEN_XPG4:
830 #ifdef	_XOPEN_XPG4
831       return _XOPEN_XPG4;
832 #else
833       RETURN_NEG_1;
834 #endif
835 
836     case _SC_CHAR_BIT:
837       return CHAR_BIT;
838 
839     case _SC_CHAR_MAX:
840       return CHAR_MAX;
841 
842     case _SC_CHAR_MIN:
843       return CHAR_MIN;
844 
845     case _SC_INT_MAX:
846       return INT_MAX;
847 
848     case _SC_INT_MIN:
849       return INT_MIN;
850 
851     case _SC_LONG_BIT:
852       return sizeof (long int) * CHAR_BIT;
853 
854     case _SC_WORD_BIT:
855       return sizeof (int) * CHAR_BIT;
856 
857     case _SC_MB_LEN_MAX:
858       return MB_LEN_MAX;
859 
860     case _SC_NZERO:
861       return NZERO;
862 
863     case _SC_SSIZE_MAX:
864       return _POSIX_SSIZE_MAX;
865 
866     case _SC_SCHAR_MAX:
867       return SCHAR_MAX;
868 
869     case _SC_SCHAR_MIN:
870       return SCHAR_MIN;
871 
872     case _SC_SHRT_MAX:
873       return SHRT_MAX;
874 
875     case _SC_SHRT_MIN:
876       return SHRT_MIN;
877 
878     case _SC_UCHAR_MAX:
879       return UCHAR_MAX;
880 
881     case _SC_UINT_MAX:
882       return UINT_MAX;
883 
884     case _SC_ULONG_MAX:
885       return ULONG_MAX;
886 
887     case _SC_USHRT_MAX:
888       return USHRT_MAX;
889 
890     case _SC_NL_ARGMAX:
891 #ifdef	NL_ARGMAX
892       return NL_ARGMAX;
893 #else
894       RETURN_NEG_1;
895 #endif
896 
897     case _SC_NL_LANGMAX:
898 #ifdef	NL_LANGMAX
899       return NL_LANGMAX;
900 #else
901       RETURN_NEG_1;
902 #endif
903 
904     case _SC_NL_MSGMAX:
905 #ifdef	NL_MSGMAX
906       return NL_MSGMAX;
907 #else
908       RETURN_NEG_1;
909 #endif
910 
911     case _SC_NL_NMAX:
912 #ifdef	NL_NMAX
913       return NL_NMAX;
914 #else
915       RETURN_NEG_1;
916 #endif
917 
918     case _SC_NL_SETMAX:
919 #ifdef	NL_SETMAX
920       return NL_SETMAX;
921 #else
922       RETURN_NEG_1;
923 #endif
924 
925     case _SC_NL_TEXTMAX:
926 #ifdef	NL_TEXTMAX
927       return NL_TEXTMAX;
928 #else
929       RETURN_NEG_1;
930 #endif
931 
932     case _SC_XBS5_ILP32_OFF32:
933 #ifdef _XBS5_ILP32_OFF32
934       return _XBS5_ILP32_OFF32;
935 #else
936       RETURN_NEG_1;
937 #endif
938     case _SC_XBS5_ILP32_OFFBIG:
939 #ifdef _XBS5_ILP32_OFFBIG
940       return _XBS5_ILP32_OFFBIG;
941 #else
942       RETURN_NEG_1;
943 #endif
944     case _SC_XBS5_LP64_OFF64:
945 #ifdef _XBS5_LP64_OFF64
946       return _XBS5_LP64_OFF64;
947 #else
948       RETURN_NEG_1;
949 #endif
950     case _SC_XBS5_LPBIG_OFFBIG:
951 #ifdef _XBS5_LPBIG_OFFBIG
952       return _XBS5_LPBIG_OFFBIG;
953 #else
954       RETURN_NEG_1;
955 #endif
956     case _SC_V7_ILP32_OFF32:
957 #ifdef _POSIX_V7_ILP32_OFF32
958       return _POSIX_V7_ILP32_OFF32;
959 #else
960       RETURN_NEG_1;
961 #endif
962     case _SC_V7_ILP32_OFFBIG:
963 #ifdef _POSIX_V7_ILP32_OFFBIG
964       return _POSIX_V7_ILP32_OFFBIG;
965 #else
966       RETURN_NEG_1;
967 #endif
968     case _SC_V7_LP64_OFF64:
969 #ifdef _POSIX_V7_LP64_OFF64
970       return _POSIX_V7_LP64_OFF64;
971 #else
972       RETURN_NEG_1;
973 #endif
974     case _SC_V7_LPBIG_OFFBIG:
975 #ifdef _POSIX_V7_LPBIG_OFFBIG
976       return _POSIX_V7_LPBIG_OFFBIG;
977 #else
978       RETURN_NEG_1;
979 #endif
980 
981     case _SC_XOPEN_LEGACY:
982       return _XOPEN_LEGACY;
983 
984     case _SC_XOPEN_REALTIME:
985 #ifdef _XOPEN_REALTIME
986       return _XOPEN_REALTIME;
987 #else
988       RETURN_NEG_1;
989 #endif
990     case _SC_XOPEN_REALTIME_THREADS:
991 #ifdef _XOPEN_REALTIME_THREADS
992       return _XOPEN_REALTIME_THREADS;
993 #else
994       RETURN_NEG_1;
995 #endif
996 
997     case _SC_MONOTONIC_CLOCK:
998 #if defined __UCLIBC_HAS_REALTIME__ && defined __NR_clock_getres
999       if (clock_getres(CLOCK_MONOTONIC, NULL) >= 0)
1000         return _POSIX_VERSION;
1001 #endif
1002       RETURN_NEG_1;
1003 
1004 #ifdef __UCLIBC_HAS_THREADS_NATIVE__
1005     case _SC_THREAD_CPUTIME:
1006 # if _POSIX_THREAD_CPUTIME > 0
1007       return _POSIX_THREAD_CPUTIME;
1008 # else
1009       RETURN_NEG_1;
1010 # endif
1011 #endif
1012     }
1013 }
1014 libc_hidden_def(sysconf)
1015