From dda1cfcf5976e27a9d70dab0a7761e27a672ba1e Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 15 Sep 2017 22:55:15 +0000 Subject: [PATCH] Add an -a flag to getconf. When -a is specified, the name and value of all system or path configuration values is reported to standard output. Reviewed by: kib (earlier version) MFC after: 1 week Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D12373 --- usr.bin/getconf/confstr.gperf | 11 ++++ usr.bin/getconf/getconf.1 | 30 ++++++++--- usr.bin/getconf/getconf.c | 94 +++++++++++++++++++++++++++++++++- usr.bin/getconf/getconf.h | 4 ++ usr.bin/getconf/pathconf.gperf | 12 +++++ usr.bin/getconf/sysconf.gperf | 11 ++++ 6 files changed, 154 insertions(+), 8 deletions(-) diff --git a/usr.bin/getconf/confstr.gperf b/usr.bin/getconf/confstr.gperf index c629987e5caf..f75ad91abd63 100644 --- a/usr.bin/getconf/confstr.gperf +++ b/usr.bin/getconf/confstr.gperf @@ -68,3 +68,14 @@ find_confstr(const char *name, int *key) } return 0; } + +void +foreach_confstr(void (*func)(const char *, int)) +{ + const struct map *mp; + + for (mp = wordlist; mp->name != NULL; mp++) { + if (mp->valid) + func(mp->name, mp->key); + } +} diff --git a/usr.bin/getconf/getconf.1 b/usr.bin/getconf/getconf.1 index 6b5116c704b5..77fdfc65ea43 100644 --- a/usr.bin/getconf/getconf.1 +++ b/usr.bin/getconf/getconf.1 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 8, 2016 +.Dd September 15, 2017 .Dt GETCONF 1 .Os .Sh NAME @@ -36,6 +36,9 @@ .Nd retrieve standard configuration variables .Sh SYNOPSIS .Nm +.Fl a +.Op Ar file +.Nm .Op Fl v Ar environment .Ar path_var .Ar file @@ -45,20 +48,35 @@ .Sh DESCRIPTION The .Nm -utility prints the value of a +utility prints the values of .Tn POSIX or .Tn X/Open -path or system configuration variable to the standard output. -If the specified variable is undefined, the string +path or system configuration variables to the standard output. +If a variable is undefined, the string .Dq Li undefined is output. .Pp -The first form of the command, with two mandatory +The first form of the command displays all of the path or system configuration +variables to standard output. +If +.Ar file +is provided, +all path configuration variables are reported for +.Ar file +using +.Xr pathconf 2 . +Otherwise, +all system configuration variables are reported using +.Xr confstr 3 +and +.Xr sysconf 3. +.Pp +The second form of the command, with two mandatory arguments, retrieves file- and file system-specific configuration variables using .Xr pathconf 2 . -The second form, with a single argument, retrieves system +The third form, with a single argument, retrieves system configuration variables using .Xr confstr 3 and diff --git a/usr.bin/getconf/getconf.c b/usr.bin/getconf/getconf.c index a82196e33d2e..7cbebfe6b183 100644 --- a/usr.bin/getconf/getconf.c +++ b/usr.bin/getconf/getconf.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -41,6 +42,8 @@ __FBSDID("$FreeBSD$"); #include "getconf.h" +static void do_allsys(void); +static void do_allpath(const char *path); static void do_confstr(const char *name, int key); static void do_sysconf(const char *name, int key); static void do_pathconf(const char *name, int key, const char *path); @@ -49,7 +52,8 @@ static void usage(void) { fprintf(stderr, -"usage: getconf [-v prog_env] system_var\n" +"usage: getconf -a [pathname]\n" +" getconf [-v prog_env] system_var\n" " getconf [-v prog_env] path_var pathname\n"); exit(EX_USAGE); } @@ -57,13 +61,18 @@ usage(void) int main(int argc, char **argv) { + bool aflag; int c, key, valid; const char *name, *vflag, *alt_path; intmax_t limitval; + aflag = false; vflag = NULL; - while ((c = getopt(argc, argv, "v:")) != -1) { + while ((c = getopt(argc, argv, "av:")) != -1) { switch (c) { + case 'a': + aflag = true; + break; case 'v': vflag = optarg; break; @@ -73,6 +82,16 @@ main(int argc, char **argv) } } + if (aflag) { + if (vflag != NULL) + usage(); + if (argv[optind] == NULL) + do_allsys(); + else + do_allpath(argv[optind]); + return (0); + } + if ((name = argv[optind]) == NULL) usage(); @@ -135,6 +154,77 @@ main(int argc, char **argv) return 0; } +static void +do_onestr(const char *name, int key) +{ + size_t len; + + errno = 0; + len = confstr(key, 0, 0); + if (len == 0 && errno != 0) { + warn("confstr: %s", name); + return; + } + printf("%s: ", name); + if (len == 0) + printf("undefined\n"); + else { + char buf[len + 1]; + + confstr(key, buf, len); + printf("%s\n", buf); + } +} + +static void +do_onesys(const char *name, int key) +{ + long value; + + errno = 0; + value = sysconf(key); + if (value == -1 && errno != 0) { + warn("sysconf: %s", name); + return; + } + printf("%s: ", name); + if (value == -1) + printf("undefined\n"); + else + printf("%ld\n", value); +} + +static void +do_allsys(void) +{ + + foreach_confstr(do_onestr); + foreach_sysconf(do_onesys); +} + +static void +do_onepath(const char *name, int key, const char *path) +{ + long value; + + errno = 0; + value = pathconf(path, key); + if (value == -1 && errno != EINVAL && errno != 0) + warn("pathconf: %s", name); + printf("%s: ", name); + if (value == -1) + printf("undefined\n"); + else + printf("%ld\n", value); +} + +static void +do_allpath(const char *path) +{ + + foreach_pathconf(do_onepath, path); +} + static void do_confstr(const char *name, int key) { diff --git a/usr.bin/getconf/getconf.h b/usr.bin/getconf/getconf.h index 266a0ff3b051..7629e2bd8116 100644 --- a/usr.bin/getconf/getconf.h +++ b/usr.bin/getconf/getconf.h @@ -41,3 +41,7 @@ int find_limit(const char *name, intmax_t *value); int find_pathconf(const char *name, int *key); int find_progenv(const char *name, const char **alt_path); int find_sysconf(const char *name, int *key); +void foreach_confstr(void (*func)(const char *, int)); +void foreach_pathconf(void (*func)(const char *, int, const char *), + const char *path); +void foreach_sysconf(void (*func)(const char *, int)); diff --git a/usr.bin/getconf/pathconf.gperf b/usr.bin/getconf/pathconf.gperf index f283546f063a..f33a66a06c7f 100644 --- a/usr.bin/getconf/pathconf.gperf +++ b/usr.bin/getconf/pathconf.gperf @@ -68,3 +68,15 @@ find_pathconf(const char *name, int *key) } return 0; } + +void +foreach_pathconf(void (*func)(const char *, int, const char *), + const char *path) +{ + const struct map *mp; + + for (mp = wordlist; mp->name != NULL; mp++) { + if (mp->valid) + func(mp->name, mp->key, path); + } +} diff --git a/usr.bin/getconf/sysconf.gperf b/usr.bin/getconf/sysconf.gperf index 6a0a34989877..d1102ef3c395 100644 --- a/usr.bin/getconf/sysconf.gperf +++ b/usr.bin/getconf/sysconf.gperf @@ -147,3 +147,14 @@ find_sysconf(const char *name, int *key) } return 0; } + +void +foreach_sysconf(void (*func)(const char *, int)) +{ + const struct map *mp; + + for (mp = wordlist; mp->name != NULL; mp++) { + if (mp->valid) + func(mp->name, mp->key); + } +}