Subject: bin/31053: Enhancement: getconf -a to list all applicable variables
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <rillig@NetBSD.org>
List: netbsd-bugs
Date: 08/24/2005 07:22:00
Note: There was a bad value `' for the field `Confidential'.
It was set to the default value of `yes'.
>Number: 31053
>Category: bin
>Synopsis: Enhancement: getconf -a to list all applicable variables
>Confidential: yes
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Wed Aug 24 07:22:00 +0000 2005
>Originator: Roland Illig
>Release: NetBSD 3.99.7
>Organization:
>Environment:
System: NetBSD baccf5ee.roland-illig.de 3.99.7 NetBSD 3.99.7 (GENERIC) #1: Mon Jul 18 06:33:01 CEST 2005 build@baccf5ee.roland-illig.de:/home/build/build-2005-07-17/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
I have extended getconf(1) to accept the -a flag instead of a variable
name. An example output is:
./getconf -a .
LINK_MAX = 32767
NAME_MAX = 255
PATH_MAX = 1024
PIPE_BUF = 512
_POSIX_CHOWN_RESTRICTED = 1
_POSIX_NO_TRUNC = 1
_POSIX_SYNC_IO = 1
FILESIZEBITS = 42
>How-To-Repeat:
>Fix:
Index: Makefile
===================================================================
RCS file: /cvsroot/src/usr.bin/getconf/Makefile,v
retrieving revision 1.4
diff -u -p -r1.4 Makefile
--- Makefile 9 Jan 1997 20:19:43 -0000 1.4
+++ Makefile 24 Aug 2005 06:44:33 -0000
@@ -1,5 +1,6 @@
# $NetBSD: Makefile,v 1.4 1997/01/09 20:19:43 tls Exp $
-PROG=getconf
+PROG= getconf
+WARNS= 4
.include <bsd.prog.mk>
Index: getconf.1
===================================================================
RCS file: /cvsroot/src/usr.bin/getconf/getconf.1,v
retrieving revision 1.9
diff -u -p -r1.9 getconf.1
--- getconf.1 10 Nov 2004 13:43:39 -0000 1.9
+++ getconf.1 24 Aug 2005 06:44:33 -0000
@@ -34,7 +34,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd November 10, 2004
+.Dd August 24, 2005
.Dt GETCONF 1
.Os
.Sh NAME
@@ -44,8 +44,13 @@
.Nm
.Ar system_var
.Nm
+.Fl a
+.Nm
.Ar path_var
.Ar pathname
+.Nm
+.Fl a
+.Ar pathname
.Sh DESCRIPTION
The
.Nm
@@ -71,6 +76,17 @@ The names of the pathname variables are
with the leading
.Dq Li _PC_
removed.
+.Pp
+When invoked with the option
+.Fl a ,
+.Nm
+writes a list of all applicable variables and their values to the
+standard output, in the format
+.Do
+.Va name
+=
+.Va value
+.Dc .
.Sh EXIT STATUS
The
.Nm
Index: getconf.c
===================================================================
RCS file: /cvsroot/src/usr.bin/getconf/getconf.c,v
retrieving revision 1.22
diff -u -p -r1.22 getconf.c
--- getconf.c 10 Nov 2004 04:02:52 -0000 1.22
+++ getconf.c 24 Aug 2005 06:44:33 -0000
@@ -50,9 +50,6 @@ __RCSID("$NetBSD: getconf.c,v 1.22 2004/
#include <unistd.h>
#include <string.h>
-int main __P((int, char **));
-static void usage __P((void));
-
struct conf_variable
{
const char *name;
@@ -60,7 +57,12 @@ struct conf_variable
long value;
};
-const struct conf_variable conf_table[] =
+static void print_longvar(const char *, long);
+static void print_strvar(const char *, const char *);
+static void printvar(const struct conf_variable *, const char *);
+static void usage(void);
+
+static const struct conf_variable conf_table[] =
{
{ "PATH", CONFSTR, _CS_PATH },
@@ -170,57 +172,101 @@ const struct conf_variable conf_table[]
{ "GETGR_R_SIZE_MAX", SYSCONF, _SC_GETGR_R_SIZE_MAX },
{ "GETPW_R_SIZE_MAX", SYSCONF, _SC_GETPW_R_SIZE_MAX },
- { NULL }
+ { NULL, CONSTANT, 0L }
};
+static int a_flag = 0; /* list all variables */
int
-main(argc, argv)
- int argc;
- char **argv;
+main(int argc, char **argv)
{
int ch;
const struct conf_variable *cp;
-
- long val;
- size_t slen;
- char * sval;
+ const char *varname, *pathname;
+ int found;
setlocale(LC_ALL, "");
- while ((ch = getopt(argc, argv, "")) != -1) {
+ while ((ch = getopt(argc, argv, "a")) != -1) {
switch (ch) {
+ case 'a':
+ a_flag = 1;
+ break;
+
case '?':
default:
usage();
+ /* NOTREACHED */
}
}
argc -= optind;
argv += optind;
- if (argc < 1 || argc > 2) {
+ varname = NULL; /* XXX: gcc -Wuninitialized */
+ if (!a_flag && argc == 0) {
usage();
/* NOTREACHED */
}
+ if (!a_flag) {
+ varname = argv[0];
+ argc--, argv++;
+ }
+ if (argc != 0 && argc != 1) {
+ usage();
+ /* NOTREACHED */
+ }
+ pathname = argv[0]; /* may be NULL */
+ found = 0;
for (cp = conf_table; cp->name != NULL; cp++) {
- if (strcmp(*argv, cp->name) == 0)
- break;
+ if (a_flag || strcmp(varname, cp->name) == 0) {
+ if ((cp->type == PATHCONF) == (pathname != NULL)) {
+ printvar (cp, pathname);
+ found = 1;
+ } else if (!a_flag) {
+ errx(1, "%s: invalid variable type", cp->name);
+ /* NOTREACHED */
+ }
+ }
}
- if (cp->name == NULL) {
- errx(1, "%s: unknown variable", *argv);
+
+ if (!a_flag && !found) {
+ errx(1, "%s: unknown variable", varname);
/* NOTREACHED */
}
- if (cp->type == PATHCONF) {
- if (argc != 2) usage();
- } else {
- if (argc != 1) usage();
- }
+ (void)fflush(stdout);
+ return ferror(stdout) ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+static void
+print_longvar(const char *name, long value)
+{
+ if (a_flag)
+ printf("%s = %ld\n", name, value);
+ else
+ printf("%ld\n", value);
+}
+
+static void
+print_strvar(const char *name, const char *sval)
+{
+ if (a_flag)
+ printf("%s = %s\n", name, sval);
+ else
+ printf("%s\n", sval);
+}
+
+static void
+printvar(const struct conf_variable *cp, const char *pathname)
+{
+ size_t slen;
+ char * sval;
+ long val;
switch (cp->type) {
case CONSTANT:
- printf("%ld\n", cp->value);
+ print_longvar(cp->name, cp->value);
break;
case CONFSTR:
@@ -230,7 +276,7 @@ main(argc, argv)
err(1, "malloc");
confstr(cp->value, sval, slen);
- printf("%s\n", sval);
+ print_strvar(cp->name, sval);
break;
case SYSCONF:
@@ -241,35 +287,38 @@ main(argc, argv)
/* NOTREACHED */
}
- printf ("undefined\n");
+ print_strvar(cp->name, "undefined");
} else {
- printf("%ld\n", val);
+ print_longvar(cp->name, val);
}
break;
case PATHCONF:
errno = 0;
- if ((val = pathconf(argv[1], cp->value)) == -1) {
+ if ((val = pathconf(pathname, cp->value)) == -1) {
if (errno != 0) {
- err(1, "%s", argv[1]);
+ if (a_flag && errno == EINVAL) {
+ /* Just skip invalid variables */
+ return;
+ }
+ err(1, "%s", pathname);
/* NOTREACHED */
}
- printf ("undefined\n");
+ print_strvar(cp->name, "undefined");
} else {
- printf ("%ld\n", val);
+ print_longvar(cp->name, val);
}
break;
}
-
- exit (ferror(stdout));
}
-
static void
-usage()
+usage(void)
{
- fprintf (stderr, "usage: getconf system_var\n");
- fprintf (stderr, " getconf path_var pathname\n");
- exit(1);
+ fprintf(stderr, "usage: getconf system_var\n");
+ fprintf(stderr, " getconf -a\n");
+ fprintf(stderr, " getconf path_var pathname\n");
+ fprintf(stderr, " getconf -a pathname\n");
+ exit(EXIT_FAILURE);
}
>Unformatted: