alicelinux

A lightweight musl + clang/llvm + libressl + busybox distro
git clone https://codeberg.org/emmett1/alicelinux
Log | Files | Refs | README | LICENSE

getconf.c (11614B)


      1 /*-
      2  * Copyright (c) 1996, 1998 The NetBSD Foundation, Inc.
      3  * All rights reserved.
      4  *
      5  * This code is derived from software contributed to The NetBSD Foundation
      6  * by J.T. Conklin.
      7  *
      8  * Mostly rewritten to be used in Alpine Linux (with musl c-library)
      9  * by Timo Teräs.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  * POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #include <err.h>
     34 #include <errno.h>
     35 #include <values.h>
     36 #include <limits.h>
     37 #include <locale.h>
     38 #include <stdio.h>
     39 #include <stdlib.h>
     40 #include <unistd.h>
     41 #include <string.h>
     42 
     43 struct conf_variable {
     44 	const char *name;
     45 	enum { SYSCONF, CONFSTR, PATHCONF, CONSTANT, UCONSTANT, NUM_TYPES } type;
     46 	long value;
     47 };
     48 
     49 static const struct conf_variable conf_table[] = {
     50 { "PATH",			CONFSTR,	_CS_PATH		},
     51 
     52 /* Utility Limit Minimum Values */
     53 { "POSIX2_BC_BASE_MAX",		CONSTANT,	_POSIX2_BC_BASE_MAX	},
     54 { "POSIX2_BC_DIM_MAX",		CONSTANT,	_POSIX2_BC_DIM_MAX	},
     55 { "POSIX2_BC_SCALE_MAX",	CONSTANT,	_POSIX2_BC_SCALE_MAX	},
     56 { "POSIX2_BC_STRING_MAX",	CONSTANT,	_POSIX2_BC_STRING_MAX	},
     57 { "POSIX2_COLL_WEIGHTS_MAX",	CONSTANT,	_POSIX2_COLL_WEIGHTS_MAX },
     58 { "POSIX2_EXPR_NEST_MAX",	CONSTANT,	_POSIX2_EXPR_NEST_MAX	},
     59 { "POSIX2_LINE_MAX",		CONSTANT,	_POSIX2_LINE_MAX	},
     60 { "POSIX2_RE_DUP_MAX",		CONSTANT,	_POSIX2_RE_DUP_MAX	},
     61 { "POSIX2_VERSION",		CONSTANT,	_POSIX2_VERSION		},
     62 
     63 /* POSIX.1 Minimum Values */
     64 { "_POSIX_AIO_LISTIO_MAX",	CONSTANT,	_POSIX_AIO_LISTIO_MAX	},
     65 { "_POSIX_AIO_MAX",		CONSTANT,       _POSIX_AIO_MAX		},
     66 { "_POSIX_ARG_MAX",		CONSTANT,	_POSIX_ARG_MAX		},
     67 { "_POSIX_CHILD_MAX",		CONSTANT,	_POSIX_CHILD_MAX	},
     68 { "_POSIX_LINK_MAX",		CONSTANT,	_POSIX_LINK_MAX		},
     69 { "_POSIX_MAX_CANON",		CONSTANT,	_POSIX_MAX_CANON	},
     70 { "_POSIX_MAX_INPUT",		CONSTANT,	_POSIX_MAX_INPUT	},
     71 { "_POSIX_MQ_OPEN_MAX",		CONSTANT,	_POSIX_MQ_OPEN_MAX	},
     72 { "_POSIX_MQ_PRIO_MAX",		CONSTANT,	_POSIX_MQ_PRIO_MAX	},
     73 { "_POSIX_NAME_MAX",		CONSTANT,	_POSIX_NAME_MAX		},
     74 { "_POSIX_NGROUPS_MAX",		CONSTANT,	_POSIX_NGROUPS_MAX	},
     75 { "_POSIX_OPEN_MAX",		CONSTANT,	_POSIX_OPEN_MAX		},
     76 { "_POSIX_PATH_MAX",		CONSTANT,	_POSIX_PATH_MAX		},
     77 { "_POSIX_PIPE_BUF",		CONSTANT,	_POSIX_PIPE_BUF		},
     78 { "_POSIX_SSIZE_MAX",		CONSTANT,	_POSIX_SSIZE_MAX	},
     79 { "_POSIX_STREAM_MAX",		CONSTANT,	_POSIX_STREAM_MAX	},
     80 { "_POSIX_TZNAME_MAX",		CONSTANT,	_POSIX_TZNAME_MAX	},
     81 
     82 /* Symbolic Utility Limits */
     83 { "BC_BASE_MAX",		SYSCONF,	_SC_BC_BASE_MAX		},
     84 { "BC_DIM_MAX",			SYSCONF,	_SC_BC_DIM_MAX		},
     85 { "BC_SCALE_MAX",		SYSCONF,	_SC_BC_SCALE_MAX	},
     86 { "BC_STRING_MAX",		SYSCONF,	_SC_BC_STRING_MAX	},
     87 { "COLL_WEIGHTS_MAX",		SYSCONF,	_SC_COLL_WEIGHTS_MAX	},
     88 { "EXPR_NEST_MAX",		SYSCONF,	_SC_EXPR_NEST_MAX	},
     89 { "LINE_MAX",			SYSCONF,	_SC_LINE_MAX		},
     90 { "RE_DUP_MAX",			SYSCONF,	_SC_RE_DUP_MAX		},
     91 
     92 /* Optional Facility Configuration Values */
     93 { "_POSIX2_C_BIND",		SYSCONF,	_SC_2_C_BIND		},
     94 { "POSIX2_C_DEV",		SYSCONF,	_SC_2_C_DEV		},
     95 { "POSIX2_CHAR_TERM",		SYSCONF,	_SC_2_CHAR_TERM		},
     96 { "POSIX2_FORT_DEV",		SYSCONF,	_SC_2_FORT_DEV		},
     97 { "POSIX2_FORT_RUN",		SYSCONF,	_SC_2_FORT_RUN		},
     98 { "POSIX2_LOCALEDEF",		SYSCONF,	_SC_2_LOCALEDEF		},
     99 { "POSIX2_SW_DEV",		SYSCONF,	_SC_2_SW_DEV		},
    100 { "POSIX2_UPE",			SYSCONF,	_SC_2_UPE		},
    101 
    102 /* POSIX.1 Configurable System Variables */
    103 { "AIO_LISTIO_MAX",		SYSCONF,	_SC_AIO_LISTIO_MAX	},
    104 { "AIO_MAX",			SYSCONF,	_SC_AIO_MAX		},
    105 { "ARG_MAX",			SYSCONF,	_SC_ARG_MAX 		},
    106 { "CHILD_MAX",			SYSCONF,	_SC_CHILD_MAX		},
    107 { "CLK_TCK",			SYSCONF,	_SC_CLK_TCK		},
    108 { "MQ_OPEN_MAX",		SYSCONF,	_SC_MQ_OPEN_MAX		},
    109 { "MQ_PRIO_MAX",		SYSCONF,	_SC_MQ_PRIO_MAX		},
    110 { "NGROUPS_MAX",		SYSCONF,	_SC_NGROUPS_MAX		},
    111 { "OPEN_MAX",			SYSCONF,	_SC_OPEN_MAX		},
    112 { "STREAM_MAX",			SYSCONF,	_SC_STREAM_MAX		},
    113 { "TZNAME_MAX",			SYSCONF,	_SC_TZNAME_MAX		},
    114 { "_POSIX_JOB_CONTROL",		SYSCONF,	_SC_JOB_CONTROL 	},
    115 { "_POSIX_SAVED_IDS",		SYSCONF,	_SC_SAVED_IDS		},
    116 { "_POSIX_VERSION",		SYSCONF,	_SC_VERSION		},
    117 
    118 { "LINK_MAX",			PATHCONF,	_PC_LINK_MAX		},
    119 { "MAX_CANON",			PATHCONF,	_PC_MAX_CANON		},
    120 { "MAX_INPUT",			PATHCONF,	_PC_MAX_INPUT		},
    121 { "NAME_MAX",			PATHCONF,	_PC_NAME_MAX		},
    122 { "PATH_MAX",			PATHCONF,	_PC_PATH_MAX		},
    123 { "PIPE_BUF",			PATHCONF,	_PC_PIPE_BUF		},
    124 { "_POSIX_CHOWN_RESTRICTED",	PATHCONF,	_PC_CHOWN_RESTRICTED	},
    125 { "_POSIX_NO_TRUNC",		PATHCONF,	_PC_NO_TRUNC		},
    126 { "_POSIX_VDISABLE",		PATHCONF,	_PC_VDISABLE		},
    127 
    128 /* POSIX.1b Configurable System Variables */
    129 { "PAGESIZE",			SYSCONF,	_SC_PAGESIZE		},
    130 { "_POSIX_ASYNCHRONOUS_IO",	SYSCONF,	_SC_ASYNCHRONOUS_IO	},
    131 { "_POSIX_FSYNC",		SYSCONF,	_SC_FSYNC		},
    132 { "_POSIX_MAPPED_FILES",	SYSCONF,	_SC_MAPPED_FILES	},
    133 { "_POSIX_MEMLOCK",		SYSCONF,	_SC_MEMLOCK		},
    134 { "_POSIX_MEMLOCK_RANGE",	SYSCONF,	_SC_MEMLOCK_RANGE	},
    135 { "_POSIX_MEMORY_PROTECTION",	SYSCONF,	_SC_MEMORY_PROTECTION	},
    136 { "_POSIX_MESSAGE_PASSING",	SYSCONF,	_SC_MESSAGE_PASSING	},
    137 { "_POSIX_MONOTONIC_CLOCK",	SYSCONF,	_SC_MONOTONIC_CLOCK	},
    138 { "_POSIX_PRIORITY_SCHEDULING", SYSCONF,	_SC_PRIORITY_SCHEDULING },
    139 { "_POSIX_SEMAPHORES",		SYSCONF,	_SC_SEMAPHORES		},
    140 { "_POSIX_SHARED_MEMORY_OBJECTS", SYSCONF,	_SC_SHARED_MEMORY_OBJECTS },
    141 { "_POSIX_SYNCHRONIZED_IO",	SYSCONF,	_SC_SYNCHRONIZED_IO	},
    142 { "_POSIX_TIMERS",		SYSCONF,	_SC_TIMERS		},
    143 
    144 { "_POSIX_SYNC_IO",		PATHCONF,	_PC_SYNC_IO		},
    145 
    146 /* POSIX.1c Configurable System Variables */
    147 { "LOGIN_NAME_MAX",		SYSCONF,	_SC_LOGIN_NAME_MAX	},
    148 { "_POSIX_THREADS",		SYSCONF,	_SC_THREADS		},
    149 
    150 /* POSIX.1j Configurable System Variables */
    151 { "_POSIX_BARRIERS",		SYSCONF,	_SC_BARRIERS		},
    152 { "_POSIX_READER_WRITER_LOCKS", SYSCONF,	_SC_READER_WRITER_LOCKS	},
    153 { "_POSIX_SPIN_LOCKS",		SYSCONF,	_SC_SPIN_LOCKS		},
    154 
    155 /* XPG4.2 Configurable System Variables */
    156 { "IOV_MAX",			SYSCONF,	_SC_IOV_MAX		},
    157 { "PAGE_SIZE",			SYSCONF,	_SC_PAGE_SIZE		},
    158 { "_XOPEN_SHM",			SYSCONF,	_SC_XOPEN_SHM		},
    159 
    160 /* X/Open CAE Spec. Issue 5 Version 2 Configurable System Variables */
    161 { "FILESIZEBITS",		PATHCONF,	_PC_FILESIZEBITS	},
    162 
    163 /* POSIX.1-2001 XSI Option Group Configurable System Variables */
    164 { "ATEXIT_MAX",			SYSCONF,	_SC_ATEXIT_MAX		},
    165 
    166 /* POSIX.1-2001 TSF Configurable System Variables */
    167 { "GETGR_R_SIZE_MAX",		SYSCONF,	_SC_GETGR_R_SIZE_MAX	},
    168 { "GETPW_R_SIZE_MAX",		SYSCONF,	_SC_GETPW_R_SIZE_MAX	},
    169 
    170 /* Commonly provided extensions */
    171 { "_PHYS_PAGES",		SYSCONF,	_SC_PHYS_PAGES		},
    172 { "_AVPHYS_PAGES",		SYSCONF,	_SC_AVPHYS_PAGES	},
    173 { "_NPROCESSORS_CONF",		SYSCONF,	_SC_NPROCESSORS_CONF	},
    174 { "_NPROCESSORS_ONLN",		SYSCONF,	_SC_NPROCESSORS_ONLN	},
    175 
    176 /* Data type related extensions */
    177 { "CHAR_BIT",			CONSTANT,	CHAR_BIT		},
    178 { "CHAR_MAX",			CONSTANT,	CHAR_MAX		},
    179 { "CHAR_MIN",			CONSTANT,	CHAR_MIN		},
    180 { "INT_MAX",			CONSTANT,	INT_MAX			},
    181 { "INT_MIN",			CONSTANT,	INT_MIN			},
    182 { "LONG_BIT",			CONSTANT,	LONG_BIT		},
    183 { "LONG_MAX",			CONSTANT,	LONG_MAX		},
    184 { "LONG_MIN",			CONSTANT,	LONG_MIN		},
    185 { "SCHAR_MAX",			CONSTANT,	SCHAR_MAX		},
    186 { "SCHAR_MIN",			CONSTANT,	SCHAR_MIN		},
    187 { "SHRT_MAX",			CONSTANT,	SHRT_MAX		},
    188 { "SHRT_MIN",			CONSTANT,	SHRT_MIN		},
    189 { "SSIZE_MAX",			CONSTANT,	SSIZE_MAX		},
    190 { "UCHAR_MAX",			UCONSTANT,	(long) UCHAR_MAX	},
    191 { "UINT_MAX",			UCONSTANT,	(long) UINT_MAX		},
    192 { "ULONG_MAX",			UCONSTANT,	(long) ULONG_MAX	},
    193 { "USHRT_MAX",			UCONSTANT,	(long) USHRT_MAX	},
    194 { "WORD_BIT",			CONSTANT,	WORD_BIT		},
    195 
    196 { NULL, CONSTANT, 0L }
    197 };
    198 
    199 static int all = 0;
    200 
    201 static void usage(const char *p)
    202 {
    203 	(void)fprintf(stderr, "Usage: %s system_var\n\t%s -a\n"
    204 	    "\t%s path_var pathname\n\t%s -a pathname\n", p, p, p, p);
    205 	exit(EXIT_FAILURE);
    206 }
    207 
    208 static void print_long(const char *name, long val)
    209 {
    210 	if (all) printf("%s = %ld\n", name, val);
    211 	else printf("%ld\n", val);
    212 }
    213 
    214 static void print_ulong(const char *name, unsigned long val)
    215 {
    216 	if (all) printf("%s = %lu\n", name, val);
    217 	else printf("%lu\n", val);
    218 }
    219 
    220 static void print_string(const char *name, const char *val)
    221 {
    222 	if (all) printf("%s = %s\n", name, val);
    223 	else printf("%s\n", val);
    224 }
    225 
    226 static int print_constant(const struct conf_variable *cp, const char *pathname)
    227 {
    228 	print_long(cp->name, cp->value);
    229 	return 0;
    230 }
    231 
    232 static int print_uconstant(const struct conf_variable *cp, const char *pathname)
    233 {
    234 	print_ulong(cp->name, (unsigned long) cp->value);
    235 	return 0;
    236 }
    237 
    238 static int print_sysconf(const struct conf_variable *cp, const char *pathname)
    239 {
    240 	long val;
    241 
    242 	errno = 0;
    243 	if ((val = sysconf((int)cp->value)) == -1) {
    244 		if (errno != 0) err(EXIT_FAILURE, "sysconf(%ld)", cp->value);
    245 		return -1;
    246 	}
    247 	print_long(cp->name, val);
    248 	return 0;
    249 }
    250 
    251 static int print_confstr(const struct conf_variable *cp, const char *pathname)
    252 {
    253 	size_t len;
    254 	char *val;
    255 
    256 	errno = 0;
    257 	if ((len = confstr((int)cp->value, NULL, 0)) == 0) goto error;
    258 	if ((val = malloc(len)) == NULL) err(EXIT_FAILURE, "Can't allocate %zu bytes", len);
    259 	errno = 0;
    260 	if (confstr((int)cp->value, val, len) == 0) goto error;
    261 	print_string(cp->name, val);
    262 	free(val);
    263 	return 0;
    264 error:
    265 	if (errno != EINVAL) err(EXIT_FAILURE, "confstr(%ld)", cp->value);
    266 	return -1;
    267 }
    268 
    269 static int print_pathconf(const struct conf_variable *cp, const char *pathname)
    270 {
    271 	long val;
    272 
    273 	errno = 0;
    274 	if ((val = pathconf(pathname, (int)cp->value)) == -1) {
    275 		if (all && errno == EINVAL) return 0;
    276 		if (errno != 0) err(EXIT_FAILURE, "pathconf(%s, %ld)", pathname, cp->value);
    277 		return -1;
    278 	}
    279 	print_long(cp->name, val);
    280 	return 0;
    281 }
    282 
    283 typedef int (*handler_t)(const struct conf_variable *cp, const char *pathname);
    284 static const handler_t type_handlers[NUM_TYPES] = {
    285 	[SYSCONF]	= print_sysconf,
    286 	[CONFSTR]	= print_confstr,
    287 	[PATHCONF]	= print_pathconf,
    288 	[CONSTANT]	= print_constant,
    289 	[UCONSTANT]	= print_uconstant,
    290 };
    291 
    292 int main(int argc, char **argv)
    293 {
    294 	const char *progname = argv[0];
    295 	const struct conf_variable *cp;
    296 	const char *varname, *pathname;
    297 	int ch, found = 0;
    298 
    299 	(void)setlocale(LC_ALL, "");
    300 	while ((ch = getopt(argc, argv, "a")) != -1) {
    301 		switch (ch) {
    302 		case 'a':
    303 			all = 1;
    304 			break;
    305 		case '?':
    306 		default:
    307 			usage(progname);
    308 		}
    309 	}
    310 	argc -= optind;
    311 	argv += optind;
    312 
    313 	if (!all) {
    314 		if (argc == 0)
    315 			usage(progname);
    316 		varname = argv[0];
    317 		argc--;
    318 		argv++;
    319 	} else
    320 		varname = NULL;
    321 
    322 	if (argc > 1)
    323 		usage(progname);
    324 	pathname = argv[0];	/* may be NULL */
    325 
    326 	for (cp = conf_table; cp->name != NULL; cp++) {
    327 		if (!all && strcmp(varname, cp->name) != 0) continue;
    328 		if ((cp->type == PATHCONF) == (pathname != NULL)) {
    329 			if (type_handlers[cp->type](cp, pathname) < 0)
    330 				print_string(cp->name, "undefined");
    331 			found = 1;
    332 		} else if (!all)
    333 			errx(EXIT_FAILURE, "%s: invalid variable type", cp->name);
    334 	}
    335 	if (!all && !found) errx(EXIT_FAILURE, "%s: unknown variable", varname);
    336 	(void)fflush(stdout);
    337 	return ferror(stdout) ? EXIT_FAILURE : EXIT_SUCCESS;
    338 }