From 52eb352e78517ec70f1b3c626a49f789274c8caa Mon Sep 17 00:00:00 2001 From: Andrew Wilcox Date: Sat, 9 Apr 2016 11:31:47 -0500 Subject: Add our first utility, getconf(1) --- getconf/getconf.1 | 110 +++++++++++ getconf/getconf.c | 540 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 650 insertions(+) create mode 100644 getconf/getconf.1 create mode 100644 getconf/getconf.c diff --git a/getconf/getconf.1 b/getconf/getconf.1 new file mode 100644 index 0000000..35f9c13 --- /dev/null +++ b/getconf/getconf.1 @@ -0,0 +1,110 @@ +.Dd April 9, 2016 +.Dt GETCONF 1 "Base Commands Manual" +.Os "Adélie Linux" + +.Sh NAME +.Nm getconf +.Nd get system configuration values + +.Sh SYNOPSIS +.Nm +.Op Fl v Ar specification +.Ar system_var + +.Nm +.Op Fl v Ar specification +.Ar path_var +.Ar pathname + +.Sh DESCRIPTION +In the first form, the +.Nm +utility prints the value of the system variable specified by +.Ar system_var +on the currently running system, under the specification given for the +.Fl v +argument if specified. + +Valid system variables are one of the following: + +.Bl -bullet -offset indent -compact +.It +The variable name of a valid parameter to the +.Xr sysconf 3 +function as specified in +.St -p1003.1-2008 , +excluding braces. The variables +.Dq _SC_CLK_TCK , +.Dq _SC_GETGR_R_SIZE_MAX , +and +.Dq _SC_GETPW_R_SIZE_MAX +are not supported. +.It +A valid parameter to the +.Xr confstr 3 +function as specified in +.St -p1003.1-2008 , +excluding the +.Dq _CS_ +prefix. +.It +A constant listed under the +.Dq Maximum Values +or +.Dq Minimum Values +section of the +.Aq Pa limits.h +header as specified in +.St -p1003.1-2008 , +excluding braces. +.El + +In the second form, the +.Nm +utility prints the value of the path variable specified by +.Ar path_var +for the path specified by +.Ar pathname +on the currently running system, under the specification given for the +.Fl v +argument if specified. + +Valid path variables are those accepted by the +.Xr fpathconf 3 +function as specified in +.St -p1003.1-2008 , +exluding braces. + +.Sh OPTIONS +.Bl -tag +.It -v +Indicates the specification to use. Currently, this option is unsupported and +will be ignored. +.El + +.Sh DIAGNOSTICS +.Ex -std + +.Sh SEE ALSO + +.Xr confstr 3 , +.Xr fpathconf 3 , +.Xr sysconf 3 . + +.Sh STANDARDS +The eventual goal for the +.Nm +utility is full conformance to +.St -p1003.1 2013 Edition. + +.Sh AUTHORS +.An A. Wilcox +.Aq awilfox@adelielinux.org + +.Sh BUGS +The +.Fl v +argument is not currently handled correctly. +.Pp +.Ar path_var +variables are not yet supported. diff --git a/getconf/getconf.c b/getconf/getconf.c new file mode 100644 index 0000000..0f2b5d0 --- /dev/null +++ b/getconf/getconf.c @@ -0,0 +1,540 @@ +/* + * getconf - get important system configuration values from the shell. + * Copyright (c) 2016 Adélie Linux Team. All rights reserved. + * Licensed under the NCSA open source license. + * See LICENSE file included with this source for more information. + */ + + +#include /* errno */ +#include /* limit_vars */ +#include /* bool type and true/false */ +#include /* stderr, fprintf */ +#include /* malloc, free */ +#include /* strlen */ +#include /* strcasecmp */ +#include /* sysconf + _SC friends, confstr + _CS friends */ + +typedef struct variable_mapping +{ + const char *variable; + const int value; +} var_map_t; + +/* For variables that are valid, but undefined in this implementation */ +#define _UNDEFINED_VARIABLE_ 0x7FEEDFEE + +const var_map_t sysconf_vars[] = { + /* max */ + { "AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX }, + { "AIO_MAX", _SC_AIO_MAX }, +#if defined(_SC_AIO_PRIO_DELTA_MAX) + { "AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX }, +#else /* NetBSD */ + { "AIO_PRIO_DELTA_MAX", _UNDEFINED_VARIABLE_ }, +#endif + { "ARG_MAX", _SC_ARG_MAX }, + { "ATEXIT_MAX", _SC_ATEXIT_MAX }, + { "BC_BASE_MAX", _SC_BC_BASE_MAX }, + { "BC_DIM_MAX", _SC_BC_DIM_MAX }, + { "BC_SCALE_MAX", _SC_BC_SCALE_MAX }, + { "BC_STRING_MAX", _SC_BC_STRING_MAX }, + { "CHILD_MAX", _SC_CHILD_MAX }, + { "COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX }, +#if defined(_SC_DELAYTIMER_MAX) + { "DELAYTIMER_MAX", _SC_DELAYTIMER_MAX }, +#else /* NetBSD */ + { "DELAYTIMER_MAX", _UNDEFINED_VARIABLE_ }, +#endif + { "EXPR_NEST_MAX", _SC_EXPR_NEST_MAX }, + { "HOST_NAME_MAX", _SC_HOST_NAME_MAX }, + { "IOV_MAX", _SC_IOV_MAX }, + { "LINE_MAX", _SC_LINE_MAX }, + { "LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX }, + { "NGROUPS_MAX", _SC_NGROUPS_MAX }, + { "MQ_OPEN_MAX", _SC_MQ_OPEN_MAX }, + { "MQ_PRIO_MAX", _SC_MQ_PRIO_MAX }, + { "OPEN_MAX", _SC_OPEN_MAX }, + { "PAGE_SIZE", _SC_PAGE_SIZE }, + { "PAGESIZE", _SC_PAGESIZE }, + { "PTHREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS }, + { "PTHREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX }, + { "PTHREAD_STACK_MIN", _SC_THREAD_STACK_MIN }, + { "PTHREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX }, + { "RE_DUP_MAX", _SC_RE_DUP_MAX }, +#if defined(_SC_RTSIG_MAX) + { "RTSIG_MAX", _SC_RTSIG_MAX }, +#else /* NetBSD */ + { "RTSIG_MAX", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_SEM_NSEMS_MAX) + { "SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX }, +#else /* NetBSD */ + { "SEM_NSEMS_MAX", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_SEM_VALUE_MAX) + { "SEM_VALUE_MAX", _SC_SEM_VALUE_MAX }, +#else /* NetBSD */ + { "SEM_VALUE_MAX", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_SIGQUEUE_MAX) + { "SIGQUEUE_MAX", _SC_SIGQUEUE_MAX }, +#else /* NetBSD */ + { "SIGQUEUE_MAX", _UNDEFINED_VARIABLE_ }, +#endif + { "STREAM_MAX", _SC_STREAM_MAX }, + { "SYMLOOP_MAX", _SC_SYMLOOP_MAX }, +#if defined(_SC_TIMER_MAX) + { "TIMER_MAX", _SC_TIMER_MAX }, +#else /* NetBSD */ + { "TIMER_MAX", _UNDEFINED_VARIABLE_ }, +#endif + { "TTY_NAME_MAX", _SC_TTY_NAME_MAX }, + { "TZNAME_MAX", _SC_TZNAME_MAX }, + + /* POSIX */ +#if defined(_SC_ADVISORY_INFO) + { "_POSIX_ADVISORY_INFO", _SC_ADVISORY_INFO }, +#else /* NetBSD */ + { "_POSIX_ADVISORY_INFO", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_BARRIERS", _SC_BARRIERS }, + { "_POSIX_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO }, + { "_POSIX_CLOCK_SELECTION", _SC_CLOCK_SELECTION }, +#if defined(_SC_CPUTIME) + { "_POSIX_CPUTIME", _SC_CPUTIME }, +#else /* NetBSD */ + { "_POSIX_CPUTIME", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_FSYNC", _SC_FSYNC }, +#if defined(_SC_IPV6) + { "_POSIX_IPV6", _SC_IPV6 }, +#else /* NetBSD */ + { "_POSIX_IPV6", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_JOB_CONTROL", _SC_JOB_CONTROL }, + { "_POSIX_MAPPED_FILES", _SC_MAPPED_FILES }, + { "_POSIX_MEMLOCK", _SC_MEMLOCK }, + { "_POSIX_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE }, + { "_POSIX_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION }, + { "_POSIX_MESSAGE_PASSING", _SC_MESSAGE_PASSING }, + { "_POSIX_MONOTONIC_CLOCK", _SC_MONOTONIC_CLOCK }, +#if defined(_SC_PRIORITIZED_IO) + { "_POSIX_PRIORITIZED_IO", _SC_PRIORITIZED_IO }, +#else /* NetBSD */ + { "_POSIX_PRIORITIZED_IO", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING }, +#if defined(_SC_RAW_SOCKETS) + { "_POSIX_RAW_SOCKETS", _SC_RAW_SOCKETS }, +#else /* NetBSD */ + { "_POSIX_RAW_SOCKETS", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_READER_WRITER_LOCKS", _SC_READER_WRITER_LOCKS }, +#if defined(_SC_REALTIME_SIGNALS) + { "_POSIX_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS }, +#else /* NetBSD */ + { "_POSIX_REALTIME_SIGNALS", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_REGEXP", _SC_REGEXP }, + { "_POSIX_SAVED_IDS", _SC_SAVED_IDS }, + { "_POSIX_SEMAPHORES", _SC_SEMAPHORES }, +#if defined(_SC_SHARED_MEMORY_OBJECTS) + { "_POSIX_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS }, +#else /* NetBSD */ + { "_POSIX_SHARED_MEMORY_OBJECTS", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_SHELL", _SC_SHELL }, + { "_POSIX_SPAWN", _SC_SPAWN }, + { "_POSIX_SPIN_LOCKS", _SC_SPIN_LOCKS }, +#if defined(_SC_SPORADIC_SERVER) + { "_POSIX_SPORADIC_SERVER", _SC_SPORADIC_SERVER }, +#else /* NetBSD */ + { "_POSIX_SPORADIC_SERVER", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_SS_REPL_MAX) + { "_POSIX_SS_REPL_MAX", _SC_SS_REPL_MAX }, +#else /* FreeBSD */ + { "_POSIX_SS_REPL_MAX", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO }, + { "_POSIX_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR }, + { "_POSIX_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE }, +#if defined(_SC_THREAD_CPUTIME) + { "_POSIX_THREAD_CPUTIME", _SC_THREAD_CPUTIME }, +#else /* NetBSD */ + { "_POSIX_THREAD_CPUTIME", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT }, + { "_POSIX_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT }, + { "_POSIX_THREAD_PRIO_PROTECT", _UNDEFINED_VARIABLE_ }, + { "_POSIX_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING }, + { "_POSIX_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED }, +#if defined(_SC_THREAD_ROBUST_PRIO_INHERIT) + { "_POSIX_THREAD_ROBUST_PRIO_INHERIT", _SC_THREAD_ROBUST_PRIO_INHERIT }, +#else /* FreeBSD */ + { "_POSIX_THREAD_ROBUST_PRIO_INHERIT", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_THREAD_ROBUST_PRIO_PROTECT) + { "_POSIX_THREAD_ROBUST_PRIO_PROTECT", _SC_THREAD_ROBUST_PRIO_PROTECT }, +#else /* FreeBSD */ + { "_POSIX_THREAD_ROBUST_PRIO_PROTECT", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS }, +#if defined(_SC_THREAD_SPORADIC_SERVER) + { "_POSIX_THREAD_SPORADIC_SERVER", _SC_THREAD_SPORADIC_SERVER }, +#else /* NetBSD */ + { "_POSIX_THREAD_SPORADIC_SERVER", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_THREADS", _SC_THREADS }, +#if defined(_SC_TIMEOUTS) + { "_POSIX_TIMEOUTS", _SC_TIMEOUTS }, +#else /* NetBSD */ + { "_POSIX_TIMEOUTS", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_TIMERS", _SC_TIMERS }, +#if defined(_SC_TRACE) + { "_POSIX_TRACE", _SC_TRACE }, +#else /* NetBSD */ + { "_POSIX_TRACE", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_TRACE_EVENT_FILTER) + { "_POSIX_TRACE_EVENT_FILTER", _SC_TRACE_EVENT_FILTER }, +#else /* NetBSD */ + { "_POSIX_TRACE_EVENT_FILTER", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_TRACE_EVENT_NAME_MAX) + { "_POSIX_TRACE_EVENT_NAME_MAX", _SC_TRACE_EVENT_NAME_MAX }, +#else /* FreeBSD */ + { "_POSIX_TRACE_EVENT_NAME_MAX", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_TRACE_INHERIT) + { "_POSIX_TRACE_INHERIT", _SC_TRACE_INHERIT }, +#else /* NetBSD */ + { "_POSIX_TRACE_INHERIT", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_TRACE_LOG) + { "_POSIX_TRACE_LOG", _SC_TRACE_LOG }, +#else /* NetBSD */ + { "_POSIX_TRACE_LOG", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_TRACE_NAME_MAX) + { "_POSIX_TRACE_NAME_MAX", _SC_TRACE_NAME_MAX }, +#else /* FreeBSD */ + { "_POSIX_TRACE_NAME_MAX", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_TRACE_SYS_MAX) + { "_POSIX_TRACE_SYS_MAX", _SC_TRACE_SYS_MAX }, +#else /* FreeBSD */ + { "_POSIX_TRACE_SYS_MAX", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_TRACE_USER_EVENT_MAX) + { "_POSIX_TRACE_USER_EVENT_MAX", _SC_TRACE_USER_EVENT_MAX }, +#else /* FreeBSD */ + { "_POSIX_TRACE_USER_EVENT_MAX", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_TYPED_MEMORY_OBJECTS) + { "_POSIX_TYPED_MEMORY_OBJECTS", _SC_TYPED_MEMORY_OBJECTS }, +#else /* NetBSD */ + { "_POSIX_TYPED_MEMORY_OBJECTS", _UNDEFINED_VARIABLE_ }, +#endif + { "_POSIX_VERSION", _SC_VERSION }, +#if defined(_SC_V7_ILP32_OFF32) + { "_POSIX_V7_ILP32_OFF32", _SC_V7_ILP32_OFF32 }, +#else /* FreeBSD */ + { "_POSIX_V7_ILP32_OFF32", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_V7_ILP32_OFFBIG) + { "_POSIX_V7_ILP32_OFFBIG", _SC_V7_ILP32_OFFBIG }, +#else /* FreeBSD */ + { "_POSIX_V7_ILP32_OFFBIG", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_V7_LP64_OFF64) + { "_POSIX_V7_LP64_OFF64", _SC_V7_LP64_OFF64 }, +#else /* FreeBSD */ + { "_POSIX_V7_LP64_OFF64", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_V7_LPBIG_OFFBIG) + { "_POSIX_V7_LPBIG_OFFBIG", _SC_V7_LPBIG_OFFBIG }, +#else /* FreeBSD */ + { "_POSIX_V7_LPBIG_OFFBIG", _UNDEFINED_VARIABLE_ }, +#endif + + /* POSIX.2 */ + { "_POSIX2_C_BIND", _SC_2_C_BIND }, + { "_POSIX2_C_DEV", _SC_2_C_DEV }, + { "_POSIX2_CHAR_TERM", _SC_2_CHAR_TERM }, + { "_POSIX2_FORT_DEV", _SC_2_FORT_DEV }, + { "_POSIX2_FORT_RUN", _SC_2_FORT_RUN }, + { "_POSIX2_LOCALEDEF", _SC_2_LOCALEDEF }, + { "_POSIX2_PBS", _SC_2_PBS }, + { "_POSIX2_PBS_ACCOUNTING", _SC_2_PBS_ACCOUNTING }, + { "_POSIX2_PBS_CHECKPOINT", _SC_2_PBS_CHECKPOINT }, + { "_POSIX2_PBS_LOCATE", _SC_2_PBS_LOCATE }, + { "_POSIX2_PBS_MESSAGE", _SC_2_PBS_MESSAGE }, + { "_POSIX2_PBS_TRACK", _SC_2_PBS_TRACK }, + { "_POSIX2_SW_DEV", _SC_2_SW_DEV }, + { "_POSIX2_UPE", _SC_2_UPE }, + { "_POSIX2_VERSION", _SC_2_VERSION }, + + /* X/Open */ +#if defined(_SC_XOPEN_CRYPT) + { "_XOPEN_CRYPT", _SC_XOPEN_CRYPT }, +#else /* NetBSD */ + { "_XOPEN_CRYPT", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_XOPEN_ENH_I18N) + { "_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N }, +#else /* NetBSD */ + { "_XOPEN_ENH_I18N", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_XOPEN_REALTIME) + { "_XOPEN_REALTIME", _SC_XOPEN_REALTIME }, +#else /* NetBSD */ + { "_XOPEN_REALTIME", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_XOPEN_REALTIME_THREADS) + { "_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS }, +#else /* NetBSD */ + { "_XOPEN_REALTIME_THREADS", _UNDEFINED_VARIABLE_ }, +#endif + { "_XOPEN_SHM", _SC_XOPEN_SHM }, +#if defined(_SC_XOPEN_STREAMS) + { "_XOPEN_STREAMS", _SC_XOPEN_STREAMS }, +#else /* NetBSD */ + { "_XOPEN_STREAMS", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_XOPEN_UNIX) + { "_XOPEN_UNIX", _SC_XOPEN_UNIX }, +#else /* NetBSD */ + { "_XOPEN_UNIX", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_XOPEN_UUCP) + { "_XOPEN_UUCP", _SC_XOPEN_UUCP }, +#else /* glibc */ + { "_XOPEN_UUCP", _UNDEFINED_VARIABLE_ }, +#endif +#if defined(_SC_XOPEN_VERSION) + { "_XOPEN_VERSION", _SC_XOPEN_VERSION } +#else /* NetBSD */ + { "_XOPEN_VERSION", _UNDEFINED_VARIABLE_ } +#endif +}; + + +const int sysvar_count = sizeof(sysconf_vars) / sizeof(sysconf_vars[0]); + + +const var_map_t confstr_vars[] = { + { "PATH", _CS_PATH }, +#if defined(_CS_V7_ENV) + { "V7_ENV", _CS_V7_ENV } +#else + { "V7_ENV", _UNDEFINED_VARIABLE_ } +#endif +}; + + +const int confstr_count = sizeof(confstr_vars) / sizeof(confstr_vars[0]); + + +const var_map_t limit_vars[] = { + { "_POSIX_AIO_LISTIO_MAX", _POSIX_AIO_LISTIO_MAX }, + { "_POSIX_AIO_MAX", _POSIX_AIO_MAX }, + { "_POSIX_ARG_MAX", _POSIX_ARG_MAX }, + { "_POSIX_CHILD_MAX", _POSIX_CHILD_MAX }, + { "_POSIX_DELAYTIMER_MAX", _POSIX_DELAYTIMER_MAX }, + { "_POSIX_HOST_NAME_MAX", _POSIX_HOST_NAME_MAX }, + { "_POSIX_LINK_MAX", _POSIX_LINK_MAX }, + { "_POSIX_LOGIN_NAME_MAX", _POSIX_LOGIN_NAME_MAX }, + { "_POSIX_MAX_CANON", _POSIX_MAX_CANON }, + { "_POSIX_MAX_INPUT", _POSIX_MAX_INPUT }, + { "_POSIX_NAME_MAX", _POSIX_NAME_MAX }, + { "_POSIX_NGROUPS_MAX", _POSIX_NGROUPS_MAX }, + { "_POSIX_OPEN_MAX", _POSIX_OPEN_MAX }, + { "_POSIX_PATH_MAX", _POSIX_PATH_MAX }, + { "_POSIX_PIPE_BUF", _POSIX_PIPE_BUF }, + { "_POSIX_RE_DUP_MAX", _POSIX_RE_DUP_MAX }, + { "_POSIX_RTSIG_MAX", _POSIX_RTSIG_MAX }, + { "_POSIX_SEM_NSEMS_MAX", _POSIX_SEM_NSEMS_MAX }, + { "_POSIX_SEM_VALUE_MAX", _POSIX_SEM_VALUE_MAX }, + { "_POSIX_SIGQUEUE_MAX", _POSIX_SIGQUEUE_MAX }, + { "_POSIX_SSIZE_MAX", _POSIX_SSIZE_MAX }, + { "_POSIX_STREAM_MAX", _POSIX_STREAM_MAX }, + { "_POSIX_SYMLINK_MAX", _POSIX_SYMLINK_MAX }, + { "_POSIX_SYMLOOP_MAX", _POSIX_SYMLOOP_MAX }, + { "_POSIX_THREAD_DESTRUCTOR_ITERATIONS", + _POSIX_THREAD_DESTRUCTOR_ITERATIONS }, + { "_POSIX_THREAD_KEYS_MAX", _POSIX_THREAD_KEYS_MAX }, + { "_POSIX_THREAD_THREADS_MAX", _POSIX_THREAD_THREADS_MAX }, + { "_POSIX_TIMER_MAX", _POSIX_TIMER_MAX }, + { "_POSIX_TTY_NAME_MAX", _POSIX_TTY_NAME_MAX }, + { "_POSIX_TZNAME_MAX", _POSIX_TZNAME_MAX }, + { "_POSIX2_BC_BASE_MAX", _POSIX2_BC_BASE_MAX }, + { "_POSIX2_BC_DIM_MAX", _POSIX2_BC_DIM_MAX }, + { "_POSIX2_BC_SCALE_MAX", _POSIX2_BC_SCALE_MAX }, + { "_POSIX2_BC_STRING_MAX", _POSIX2_BC_STRING_MAX }, + { "_POSIX2_CHARCLASS_NAME_MAX", _POSIX2_CHARCLASS_NAME_MAX }, + { "_POSIX2_COLL_WEIGHTS_MAX", _POSIX2_COLL_WEIGHTS_MAX }, + { "_POSIX2_EXPR_NEST_MAX", _POSIX2_EXPR_NEST_MAX }, + { "_POSIX2_LINE_MAX", _POSIX2_LINE_MAX }, + { "_POSIX2_RE_DUP_MAX", _POSIX2_RE_DUP_MAX } +}; + + +const int limit_count = sizeof(limit_vars) / sizeof(limit_vars[0]); + + +int do_system_var(char *environment, char *system_var) +{ + int var; + + if(strlen(environment) != 0) + { + fprintf(stderr, "Unsupported environment: %s\n", environment); + return EINVAL; + } + + for(var = 0; var < sysvar_count; var++) + { + long int val; + + if(strcasecmp(sysconf_vars[var].variable, system_var) != 0) + continue; + + if(sysconf_vars[var].value == _UNDEFINED_VARIABLE_) + { + printf("undefined\n"); + return 0; + } + + errno = 0; + + val = sysconf(sysconf_vars[var].value); + if(errno != 0) + { + /* We know that this is a valid symbol, so don't break + * expectations (see _POSIX_TRACE_LOG in FreeBSD). + * + * Note that POSIX states explicitly that results are + * already unspecified if the value is dependent on an + * unsupported POSIX option. It also indicates that + * *all* variables defined for sysconf *must* return + * a result in getconf. So, I feel this is the + * strictest way to conform. + */ + printf("undefined\n"); + return 0; + } + + printf("%ld\n", val); + return 0; + } + + for(var = 0; var < limit_count; var++) + { + if(strcasecmp(limit_vars[var].variable, system_var) != 0) + continue; + + printf("%d\n", limit_vars[var].value); + return 0; + } + + for(var = 0; var < confstr_count; var++) + { + size_t str_len; + char *str; + + if(strcasecmp(confstr_vars[var].variable, system_var) != 0) + continue; + + if(confstr_vars[var].value == _UNDEFINED_VARIABLE_) + { + printf("undefined\n"); + return 0; + } + + errno = 0; + + str_len = confstr(confstr_vars[var].value, NULL, 0); + if(errno != 0 || str_len == 0) + { + /* We know that this is a valid symbol, so don't break + * expectations (see above comment for sysconf). + */ + printf("undefined\n"); + return 0; + } + + str = malloc(str_len); + confstr(confstr_vars[var].value, str, str_len); + printf("%s\n", str); + free(str); + + return 0; + } + + fprintf(stderr, "%s: not a recognised system variable\n", system_var); + return EINVAL; +} + + +int do_path_var(char *environment, char *path_var, char *pathname) +{ + return -1; +} + + +int main(int argc, char *argv[]) +{ + /* The envrionment passed by -v, if any. Ignored for now. */ + char *environment = NULL; + /* An error occurred during argument parsing */ + bool arg_error = false; + /* The current argument being parsed */ + int arg; + + while((arg = getopt(argc, argv, ":v:")) != -1) + { + switch(arg) + { + case 'v': + environment = optarg; + break; + case ':': + fprintf(stderr, "required argument to '-%c' missing\n", + optopt); + arg_error = true; + break; + case '?': + default: + fprintf(stderr, "unrecognised option: '-%c'\n", optopt); + arg_error = true; + break; + } + } + + switch(argc - optind) + { + case 1: + return do_system_var(environment, argv[optind++]); + case 2: + return do_path_var(environment, argv[optind], argv[optind+1]); + default: + /* just show usage. */ + arg_error = true; + break; + } + + if(arg_error) + { + fprintf(stderr, "usage:\n"); + fprintf(stderr, "getconf [-v specification] system_var\n"); + fprintf(stderr, + "getconf [-v specification] path_var pathname\n"); + fprintf(stderr, "\n\tRetrieve system configuration value.\n"); + return EINVAL; + } + + return 0; +} -- cgit v1.2.3-60-g2f50