Index: head/usr.bin/getconf/confstr.gperf =================================================================== --- head/usr.bin/getconf/confstr.gperf +++ head/usr.bin/getconf/confstr.gperf @@ -68,3 +68,14 @@ } 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); + } +} Index: head/usr.bin/getconf/getconf.h =================================================================== --- head/usr.bin/getconf/getconf.h +++ head/usr.bin/getconf/getconf.h @@ -41,3 +41,7 @@ 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)); Index: head/usr.bin/getconf/getconf.1 =================================================================== --- head/usr.bin/getconf/getconf.1 +++ head/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 Index: head/usr.bin/getconf/getconf.c =================================================================== --- head/usr.bin/getconf/getconf.c +++ head/usr.bin/getconf/getconf.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,8 @@ #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 @@ 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 @@ 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 @@ } } + 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(); @@ -133,6 +152,77 @@ name); } 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 Index: head/usr.bin/getconf/pathconf.gperf =================================================================== --- head/usr.bin/getconf/pathconf.gperf +++ head/usr.bin/getconf/pathconf.gperf @@ -68,3 +68,15 @@ } 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); + } +} Index: head/usr.bin/getconf/sysconf.gperf =================================================================== --- head/usr.bin/getconf/sysconf.gperf +++ head/usr.bin/getconf/sysconf.gperf @@ -147,3 +147,14 @@ } 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); + } +}