10f66f451Sopenharmony_ci/* getconf.c - get configuration values 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2017 Rob Landley <rob@landley.net> 40f66f451Sopenharmony_ci * 50f66f451Sopenharmony_ci * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getconf.c 60f66f451Sopenharmony_ci * 70f66f451Sopenharmony_ci * Deviations from posix: no -v because nothing says what it should DO. 80f66f451Sopenharmony_ci * Added -l, what symbols should be included is a bit unclear. 90f66f451Sopenharmony_ci * Added -a, copied FSF behavior of assuming "/" if no path supplied. 100f66f451Sopenharmony_ci 110f66f451Sopenharmony_ciUSE_GETCONF(NEWTOY(getconf, ">2al", TOYFLAG_USR|TOYFLAG_BIN)) 120f66f451Sopenharmony_ci 130f66f451Sopenharmony_ciconfig GETCONF 140f66f451Sopenharmony_ci bool "getconf" 150f66f451Sopenharmony_ci default y 160f66f451Sopenharmony_ci help 170f66f451Sopenharmony_ci usage: getconf -a [PATH] | -l | NAME [PATH] 180f66f451Sopenharmony_ci 190f66f451Sopenharmony_ci Get system configuration values. Values from pathconf(3) require a path. 200f66f451Sopenharmony_ci 210f66f451Sopenharmony_ci -a Show all (defaults to "/" if no path given) 220f66f451Sopenharmony_ci -l List available value names (grouped by source) 230f66f451Sopenharmony_ci*/ 240f66f451Sopenharmony_ci 250f66f451Sopenharmony_ci#define FOR_getconf 260f66f451Sopenharmony_ci#include "toys.h" 270f66f451Sopenharmony_ci#include <limits.h> 280f66f451Sopenharmony_ci 290f66f451Sopenharmony_ci// This is missing on glibc (bionic has it). 300f66f451Sopenharmony_ci#ifndef _SC_XOPEN_UUCP 310f66f451Sopenharmony_ci#define _SC_XOPEN_UUCP -1 320f66f451Sopenharmony_ci#endif 330f66f451Sopenharmony_ci 340f66f451Sopenharmony_ci#ifdef __APPLE__ 350f66f451Sopenharmony_ci// macOS doesn't have a bunch of stuff. The actual macOS getconf says 360f66f451Sopenharmony_ci// "no such parameter", but -- unless proven otherwise -- it seems more useful 370f66f451Sopenharmony_ci// for portability if we act like we understood but say "undefined"? 380f66f451Sopenharmony_ci#define _SC_AVPHYS_PAGES -1 390f66f451Sopenharmony_ci#define _SC_THREAD_ROBUST_PRIO_INHERIT -1 400f66f451Sopenharmony_ci#define _SC_THREAD_ROBUST_PRIO_PROTECT -1 410f66f451Sopenharmony_ci#define _SC_UIO_MAXIOV -1 420f66f451Sopenharmony_ci#define _SC_V7_ILP32_OFF32 -1 430f66f451Sopenharmony_ci#define _SC_V7_ILP32_OFFBIG -1 440f66f451Sopenharmony_ci#define _SC_V7_LP64_OFF64 -1 450f66f451Sopenharmony_ci#define _SC_V7_LPBIG_OFFBIG -1 460f66f451Sopenharmony_ci#define _CS_V7_ENV -1 470f66f451Sopenharmony_ci#endif 480f66f451Sopenharmony_ci 490f66f451Sopenharmony_cistruct config { 500f66f451Sopenharmony_ci char *name; 510f66f451Sopenharmony_ci long long value; 520f66f451Sopenharmony_ci}; 530f66f451Sopenharmony_ci 540f66f451Sopenharmony_ci// Lists of symbols getconf can query, broken down by whether we call sysconf(), 550f66f451Sopenharmony_ci// confstr(), or output the macro value directly. 560f66f451Sopenharmony_ci 570f66f451Sopenharmony_ci// Probe the live system 580f66f451Sopenharmony_cistruct config sysconfs[] = { 590f66f451Sopenharmony_ci /* POSIX */ 600f66f451Sopenharmony_ci#define CONF(n) {"_POSIX_" #n,_SC_ ## n} 610f66f451Sopenharmony_ci CONF(ADVISORY_INFO), CONF(BARRIERS), CONF(ASYNCHRONOUS_IO), 620f66f451Sopenharmony_ci CONF(CLOCK_SELECTION), CONF(CPUTIME), CONF(FSYNC), CONF(IPV6), 630f66f451Sopenharmony_ci CONF(JOB_CONTROL), CONF(MAPPED_FILES), CONF(MEMLOCK), CONF(MEMLOCK_RANGE), 640f66f451Sopenharmony_ci CONF(MEMORY_PROTECTION), CONF(MESSAGE_PASSING), CONF(MONOTONIC_CLOCK), 650f66f451Sopenharmony_ci CONF(PRIORITY_SCHEDULING), CONF(RAW_SOCKETS), CONF(READER_WRITER_LOCKS), 660f66f451Sopenharmony_ci CONF(REALTIME_SIGNALS), CONF(REGEXP), CONF(SAVED_IDS), CONF(SEMAPHORES), 670f66f451Sopenharmony_ci CONF(SHARED_MEMORY_OBJECTS), CONF(SHELL), CONF(SPAWN), CONF(SPIN_LOCKS), 680f66f451Sopenharmony_ci CONF(SPORADIC_SERVER), CONF(SS_REPL_MAX), CONF(SYNCHRONIZED_IO), 690f66f451Sopenharmony_ci CONF(THREAD_ATTR_STACKADDR), CONF(THREAD_ATTR_STACKSIZE), 700f66f451Sopenharmony_ci CONF(THREAD_CPUTIME), CONF(THREAD_PRIO_INHERIT), CONF(THREAD_PRIO_PROTECT), 710f66f451Sopenharmony_ci CONF(THREAD_PRIORITY_SCHEDULING), CONF(THREAD_PROCESS_SHARED), 720f66f451Sopenharmony_ci CONF(THREAD_ROBUST_PRIO_INHERIT), CONF(THREAD_ROBUST_PRIO_PROTECT), 730f66f451Sopenharmony_ci CONF(THREAD_SAFE_FUNCTIONS), CONF(THREAD_SPORADIC_SERVER), CONF(THREADS), 740f66f451Sopenharmony_ci CONF(TIMEOUTS), CONF(TIMERS), CONF(TRACE), CONF(TRACE_EVENT_FILTER), 750f66f451Sopenharmony_ci CONF(TRACE_EVENT_NAME_MAX), CONF(TRACE_INHERIT), CONF(TRACE_LOG), 760f66f451Sopenharmony_ci CONF(TRACE_NAME_MAX), CONF(TRACE_SYS_MAX), CONF(TRACE_USER_EVENT_MAX), 770f66f451Sopenharmony_ci CONF(TYPED_MEMORY_OBJECTS), CONF(VERSION), CONF(V7_ILP32_OFF32), 780f66f451Sopenharmony_ci CONF(V7_ILP32_OFFBIG), CONF(V7_LP64_OFF64), CONF(V7_LPBIG_OFFBIG), 790f66f451Sopenharmony_ci 800f66f451Sopenharmony_ci /* POSIX.2 */ 810f66f451Sopenharmony_ci#undef CONF 820f66f451Sopenharmony_ci#define CONF(n) {"POSIX2_" #n,_SC_2_ ## n} 830f66f451Sopenharmony_ci CONF(C_BIND), CONF(C_DEV), CONF(CHAR_TERM), CONF(FORT_DEV), CONF(FORT_RUN), 840f66f451Sopenharmony_ci CONF(LOCALEDEF), CONF(PBS), CONF(PBS_ACCOUNTING), CONF(PBS_CHECKPOINT), 850f66f451Sopenharmony_ci CONF(PBS_LOCATE), CONF(PBS_MESSAGE), CONF(PBS_TRACK), CONF(SW_DEV), 860f66f451Sopenharmony_ci CONF(UPE), CONF(VERSION), 870f66f451Sopenharmony_ci 880f66f451Sopenharmony_ci /* X/Open */ 890f66f451Sopenharmony_ci#undef CONF 900f66f451Sopenharmony_ci#define CONF(n) {"_XOPEN_" #n,_SC_XOPEN_ ## n} 910f66f451Sopenharmony_ci CONF(CRYPT), CONF(ENH_I18N), CONF(REALTIME), CONF(REALTIME_THREADS), 920f66f451Sopenharmony_ci CONF(SHM), CONF(STREAMS), CONF(UNIX), CONF(UUCP), CONF(VERSION), 930f66f451Sopenharmony_ci 940f66f451Sopenharmony_ci /* No obvious standard */ 950f66f451Sopenharmony_ci#undef CONF 960f66f451Sopenharmony_ci#define CONF(n) {#n,_SC_ ## n} 970f66f451Sopenharmony_ci CONF(AIO_LISTIO_MAX), CONF(AIO_MAX), CONF(AIO_PRIO_DELTA_MAX), CONF(ARG_MAX), 980f66f451Sopenharmony_ci CONF(ATEXIT_MAX), CONF(BC_BASE_MAX), CONF(BC_DIM_MAX), CONF(BC_SCALE_MAX), 990f66f451Sopenharmony_ci CONF(BC_STRING_MAX), CONF(CHILD_MAX), CONF(CLK_TCK), CONF(COLL_WEIGHTS_MAX), 1000f66f451Sopenharmony_ci CONF(DELAYTIMER_MAX), CONF(EXPR_NEST_MAX), CONF(HOST_NAME_MAX), 1010f66f451Sopenharmony_ci CONF(IOV_MAX), CONF(LINE_MAX), CONF(LOGIN_NAME_MAX), CONF(NGROUPS_MAX), 1020f66f451Sopenharmony_ci CONF(MQ_OPEN_MAX), CONF(MQ_PRIO_MAX), CONF(OPEN_MAX), CONF(PAGE_SIZE), 1030f66f451Sopenharmony_ci CONF(PAGESIZE), CONF(RAW_SOCKETS), CONF(RE_DUP_MAX), CONF(RTSIG_MAX), 1040f66f451Sopenharmony_ci CONF(SEM_NSEMS_MAX), CONF(SEM_VALUE_MAX), CONF(SIGQUEUE_MAX), 1050f66f451Sopenharmony_ci CONF(STREAM_MAX), CONF(SYMLOOP_MAX), CONF(TIMER_MAX), CONF(TTY_NAME_MAX), 1060f66f451Sopenharmony_ci CONF(TZNAME_MAX), CONF(UIO_MAXIOV), 1070f66f451Sopenharmony_ci 1080f66f451Sopenharmony_ci /* Names that just don't match the symbol, do it by hand */ 1090f66f451Sopenharmony_ci {"_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, {"_PHYS_PAGES", _SC_PHYS_PAGES}, 1100f66f451Sopenharmony_ci {"_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, 1110f66f451Sopenharmony_ci {"_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, 1120f66f451Sopenharmony_ci 1130f66f451Sopenharmony_ci /* There's a weird "PTHREAD" vs "THREAD" mismatch here. */ 1140f66f451Sopenharmony_ci {"PTHREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, 1150f66f451Sopenharmony_ci {"PTHREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, 1160f66f451Sopenharmony_ci {"PTHREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, 1170f66f451Sopenharmony_ci {"PTHREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, 1180f66f451Sopenharmony_ci}; 1190f66f451Sopenharmony_ci 1200f66f451Sopenharmony_ci// Probe the live system with a path 1210f66f451Sopenharmony_cistruct config pathconfs[] = { 1220f66f451Sopenharmony_ci#undef CONF 1230f66f451Sopenharmony_ci#define CONF(n) {#n,_PC_ ## n} 1240f66f451Sopenharmony_ci CONF(ASYNC_IO), CONF(CHOWN_RESTRICTED), CONF(FILESIZEBITS), CONF(LINK_MAX), 1250f66f451Sopenharmony_ci CONF(MAX_CANON), CONF(MAX_INPUT), CONF(NAME_MAX), CONF(NO_TRUNC), 1260f66f451Sopenharmony_ci CONF(PATH_MAX), CONF(PIPE_BUF), CONF(PRIO_IO), CONF(SYMLINK_MAX), 1270f66f451Sopenharmony_ci CONF(SYNC_IO), 1280f66f451Sopenharmony_ci {"_POSIX_VDISABLE", _PC_VDISABLE}, 1290f66f451Sopenharmony_ci}; 1300f66f451Sopenharmony_ci 1310f66f451Sopenharmony_ci// Strings out of a header 1320f66f451Sopenharmony_cistruct config confstrs[] = { 1330f66f451Sopenharmony_ci#undef CONF 1340f66f451Sopenharmony_ci#define CONF(n) {#n,_CS_ ## n} 1350f66f451Sopenharmony_ci CONF(PATH), CONF(V7_ENV) 1360f66f451Sopenharmony_ci}; 1370f66f451Sopenharmony_ci 1380f66f451Sopenharmony_ci// Integers out of a header 1390f66f451Sopenharmony_cistruct config limits[] = { 1400f66f451Sopenharmony_ci#undef CONF 1410f66f451Sopenharmony_ci#define CONF(n) {#n,n} 1420f66f451Sopenharmony_ci CONF(_POSIX_AIO_LISTIO_MAX), CONF(_POSIX_AIO_MAX), CONF(_POSIX_ARG_MAX), 1430f66f451Sopenharmony_ci CONF(_POSIX_CHILD_MAX), CONF(_POSIX_DELAYTIMER_MAX), 1440f66f451Sopenharmony_ci CONF(_POSIX_HOST_NAME_MAX), CONF(_POSIX_LINK_MAX), 1450f66f451Sopenharmony_ci CONF(_POSIX_LOGIN_NAME_MAX), CONF(_POSIX_MAX_CANON), 1460f66f451Sopenharmony_ci CONF(_POSIX_MAX_INPUT), CONF(_POSIX_NAME_MAX), CONF(_POSIX_NGROUPS_MAX), 1470f66f451Sopenharmony_ci CONF(_POSIX_OPEN_MAX), CONF(_POSIX_PATH_MAX), CONF(_POSIX_PIPE_BUF), 1480f66f451Sopenharmony_ci CONF(_POSIX_RE_DUP_MAX), CONF(_POSIX_RTSIG_MAX), CONF(_POSIX_SEM_NSEMS_MAX), 1490f66f451Sopenharmony_ci CONF(_POSIX_SEM_VALUE_MAX), CONF(_POSIX_SIGQUEUE_MAX), CONF(_POSIX_SSIZE_MAX), 1500f66f451Sopenharmony_ci CONF(_POSIX_STREAM_MAX), CONF(_POSIX_SYMLINK_MAX), CONF(_POSIX_SYMLOOP_MAX), 1510f66f451Sopenharmony_ci CONF(_POSIX_THREAD_DESTRUCTOR_ITERATIONS), CONF(_POSIX_THREAD_KEYS_MAX), 1520f66f451Sopenharmony_ci CONF(_POSIX_THREAD_THREADS_MAX), CONF(_POSIX_TIMER_MAX), 1530f66f451Sopenharmony_ci CONF(_POSIX_TTY_NAME_MAX), CONF(_POSIX_TZNAME_MAX), 1540f66f451Sopenharmony_ci CONF(CHAR_MAX), CONF(CHAR_MIN), CONF(INT_MAX), CONF(INT_MIN), CONF(SCHAR_MAX), 1550f66f451Sopenharmony_ci CONF(SCHAR_MIN), CONF(SHRT_MAX), CONF(SHRT_MIN), CONF(SSIZE_MAX), 1560f66f451Sopenharmony_ci CONF(UCHAR_MAX), CONF(UINT_MAX), CONF(ULONG_MAX), CONF(USHRT_MAX), 1570f66f451Sopenharmony_ci CONF(CHAR_BIT), 1580f66f451Sopenharmony_ci /* Not available in glibc without _GNU_SOURCE. */ 1590f66f451Sopenharmony_ci {"LONG_BIT", 8*sizeof(long)}, 1600f66f451Sopenharmony_ci {"WORD_BIT", 8*sizeof(int)}, 1610f66f451Sopenharmony_ci#undef CONF 1620f66f451Sopenharmony_ci#define CONF(n) {#n,_ ## n} 1630f66f451Sopenharmony_ci CONF(POSIX2_BC_BASE_MAX), CONF(POSIX2_BC_DIM_MAX), 1640f66f451Sopenharmony_ci CONF(POSIX2_BC_SCALE_MAX), CONF(POSIX2_BC_STRING_MAX), 1650f66f451Sopenharmony_ci CONF(POSIX2_CHARCLASS_NAME_MAX), CONF(POSIX2_COLL_WEIGHTS_MAX), 1660f66f451Sopenharmony_ci CONF(POSIX2_EXPR_NEST_MAX), CONF(POSIX2_LINE_MAX), CONF(POSIX2_RE_DUP_MAX), 1670f66f451Sopenharmony_ci}; 1680f66f451Sopenharmony_ci 1690f66f451Sopenharmony_ci// Names we need to handle ourselves (default to blank but shouldn't error) 1700f66f451Sopenharmony_cistruct config others[] = { 1710f66f451Sopenharmony_ci {"LFS_CFLAGS", 0}, {"LFS_LDFLAGS", 0}, {"LFS_LIBS", 0} 1720f66f451Sopenharmony_ci}; 1730f66f451Sopenharmony_ci 1740f66f451Sopenharmony_cistatic void show_conf(int i, struct config *c, const char *path) 1750f66f451Sopenharmony_ci{ 1760f66f451Sopenharmony_ci if (i<2) { 1770f66f451Sopenharmony_ci long l = i ? pathconf(path, c->value) : sysconf(c->value); 1780f66f451Sopenharmony_ci 1790f66f451Sopenharmony_ci if (l == -1) puts("undefined"); 1800f66f451Sopenharmony_ci else printf("%ld\n", l); 1810f66f451Sopenharmony_ci } else if (i==2) { 1820f66f451Sopenharmony_ci confstr(c->value, toybuf, sizeof(toybuf)); 1830f66f451Sopenharmony_ci puts(toybuf); 1840f66f451Sopenharmony_ci } else if (i==3) printf("%lld\n", c->value); 1850f66f451Sopenharmony_ci // LFS_CFLAGS on 32 bit should enable Large File Support for kernel builds 1860f66f451Sopenharmony_ci else puts(sizeof(long)==4 && !strcmp(c->name, "LFS_CFLAGS") ? 1870f66f451Sopenharmony_ci "-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" : ""); 1880f66f451Sopenharmony_ci} 1890f66f451Sopenharmony_ci 1900f66f451Sopenharmony_civoid getconf_main(void) 1910f66f451Sopenharmony_ci{ 1920f66f451Sopenharmony_ci struct config *configs[] = {sysconfs, pathconfs, confstrs, limits, others}, 1930f66f451Sopenharmony_ci *c = NULL; 1940f66f451Sopenharmony_ci int i, j, lens[] = {ARRAY_LEN(sysconfs), ARRAY_LEN(pathconfs), 1950f66f451Sopenharmony_ci ARRAY_LEN(confstrs), ARRAY_LEN(limits), ARRAY_LEN(others)}; 1960f66f451Sopenharmony_ci char *name, *path = (toys.optc==2) ? toys.optargs[1] : "/", 1970f66f451Sopenharmony_ci *config_names[] = {"sysconf(3)", "pathconf(3)", "confstr(3)", 1980f66f451Sopenharmony_ci "<limits.h>", "Misc"}; 1990f66f451Sopenharmony_ci 2000f66f451Sopenharmony_ci if (toys.optflags&FLAG_a) { 2010f66f451Sopenharmony_ci for (i = 0; i<5; i++) { 2020f66f451Sopenharmony_ci for (j = 0; j<lens[i]; j++) { 2030f66f451Sopenharmony_ci c = &configs[i][j]; 2040f66f451Sopenharmony_ci printf("%-34s ", c->name); 2050f66f451Sopenharmony_ci show_conf(i, c, path); 2060f66f451Sopenharmony_ci } 2070f66f451Sopenharmony_ci } 2080f66f451Sopenharmony_ci return; 2090f66f451Sopenharmony_ci } 2100f66f451Sopenharmony_ci 2110f66f451Sopenharmony_ci if (toys.optflags&FLAG_l) { 2120f66f451Sopenharmony_ci for (i = 0; i<5; i++) { 2130f66f451Sopenharmony_ci printf("%s\n", config_names[i]); 2140f66f451Sopenharmony_ci for (j = 0; j<lens[i]; j++) printf(" %s\n", configs[i][j].name); 2150f66f451Sopenharmony_ci } 2160f66f451Sopenharmony_ci return; 2170f66f451Sopenharmony_ci } 2180f66f451Sopenharmony_ci 2190f66f451Sopenharmony_ci if (toys.optc<1) help_exit(0); 2200f66f451Sopenharmony_ci name = *toys.optargs; 2210f66f451Sopenharmony_ci 2220f66f451Sopenharmony_ci // Workaround for autogen using CS_PATH instead of PATH 2230f66f451Sopenharmony_ci if (!strcmp("CS_PATH", name)) name += 3; 2240f66f451Sopenharmony_ci 2250f66f451Sopenharmony_ci // Find the config. 2260f66f451Sopenharmony_ci for (i = j = 0; ; j++) { 2270f66f451Sopenharmony_ci if (j==lens[i]) j = 0, i++; 2280f66f451Sopenharmony_ci if (i==5) error_exit("bad '%s'", name); 2290f66f451Sopenharmony_ci c = &configs[i][j]; 2300f66f451Sopenharmony_ci if (!strcmp(c->name, name)) break; 2310f66f451Sopenharmony_ci } 2320f66f451Sopenharmony_ci 2330f66f451Sopenharmony_ci // Check that we do/don't have the extra path argument. 2340f66f451Sopenharmony_ci if (i==1) { 2350f66f451Sopenharmony_ci if (toys.optc!=2) help_exit("%s needs a path", name); 2360f66f451Sopenharmony_ci } else if (toys.optc!=1) help_exit("%s does not take a path", name); 2370f66f451Sopenharmony_ci 2380f66f451Sopenharmony_ci show_conf(i, c, path); 2390f66f451Sopenharmony_ci} 240