Discussion:
[PATCH] getconf: add pathconf(3) variables.
Add Reply
enh
2018-10-02 23:20:56 UTC
Reply
Permalink
Also improve the -l output to include sections (because you need to
know whether you're dealing with a pathconf variable to supply the
required path).
---
toys/posix/getconf.c | 87 +++++++++++++++++++++++++++-----------------
1 file changed, 54 insertions(+), 33 deletions(-)

diff --git a/toys/posix/getconf.c b/toys/posix/getconf.c
index a9ef298..d10365b 100644
--- a/toys/posix/getconf.c
+++ b/toys/posix/getconf.c
@@ -6,17 +6,19 @@
*
* Deviations from posix: no -v because nothing says what it should DO.

-USE_GETCONF(NEWTOY(getconf, "l", TOYFLAG_USR|TOYFLAG_BIN))
+USE_GETCONF(NEWTOY(getconf, ">2l", TOYFLAG_USR|TOYFLAG_BIN))

config GETCONF
bool "getconf"
default y
help
- usage: getconf [-l] [NAME...]
+ usage: getconf -l
+ usage: getconf NAME
+ usage: getconf NAME PATH

- Get system configuration values.
+ Get system configuration values. Values from pathconf(3) require a path.

- -l List available value names
+ -l List available value names (grouped by source)
*/

#define FOR_getconf
@@ -94,6 +96,16 @@ struct config sysconfs[] = {
CONF(NPROCESSORS_ONLN)
};

+// Probe the live system with a path
+struct config pathconfs[] = {
+#undef CONF
+#define CONF(n) {#n,_PC_ ## n}
+ CONF(ASYNC_IO), CONF(CHOWN_RESTRICTED), CONF(FILESIZEBITS), CONF(LINK_MAX),
+ CONF(MAX_CANON), CONF(MAX_INPUT), CONF(NAME_MAX), CONF(NO_TRUNC),
+ CONF(PATH_MAX), CONF(PIPE_BUF), CONF(PRIO_IO), CONF(SYMLINK_MAX),
+ CONF(SYNC_IO), CONF(VDISABLE),
+};
+
// Strings out of a header
struct config confstrs[] = {
#undef CONF
@@ -130,41 +142,50 @@ struct config others[] = {

void getconf_main(void)
{
- struct config *configs[] = {sysconfs, confstrs, limits, others};
- char **args;
- int i, j, lens[] = {ARRAY_LEN(sysconfs), ARRAY_LEN(confstrs),
- ARRAY_LEN(limits), ARRAY_LEN(others)};
+ struct config *configs[] = {sysconfs, pathconfs, confstrs, limits, others},
+ *c = NULL;
+ int i, j, lens[] = {ARRAY_LEN(sysconfs), ARRAY_LEN(pathconfs),
+ ARRAY_LEN(confstrs), ARRAY_LEN(limits), ARRAY_LEN(others)};
+ char *name, *config_names[] = {"sysconf(3)", "pathconf(3)", "confstr(3)",
+ "<limits.h>", "Misc"};

if (toys.optflags&FLAG_l) {
- for (i = 0; i<4; i++) for (j = 0; j<lens[i]; j++) puts(configs[i][j].name);
-
+ for (i = 0; i<5; i++) {
+ printf("%s\n", config_names[i]);
+ for (j = 0; j<lens[i]; j++) {
+ printf(" %s\n", configs[i][j].name);
+ }
+ }
return;
}

- for (args = toys.optargs; *args; args++) {
- char *name = *args;
+ if (toys.optc<1) help_exit(0);
+ name = *toys.optargs;

- // Workaround for autogen using CS_PATH instead of PATH
- if (!strcmp("CS_PATH", name)) name += 3;
+ // Workaround for autogen using CS_PATH instead of PATH
+ if (!strcmp("CS_PATH", name)) name += 3;

- for (i = 0; i<4; i++) for (j = 0; j<lens[i]; j++) {
- struct config *c = &configs[i][j];
-
- if (strcmp(c->name, name)) continue;
-
- if (!i) printf("%ld\n", sysconf(c->value));
- else if (i==1) {
- confstr(c->value, toybuf, sizeof(toybuf));
- puts(toybuf);
- } else if (i==2) printf("%d\n", c->value);
- // For legacy kernel build
- else if (sizeof(long)==4 && !j)
- puts("-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64");
-
- goto cont;
- }
- error_msg("bad '%s'", name);
-cont:
- ;
+ // Find the config.
+ for (i = 0; i<5; i++) for (j = 0; j<lens[i]; j++) {
+ c = &configs[i][j];
+ if (!strcmp(c->name, name)) goto found;
+ }
+ error_msg("bad '%s'", name);
+
+ found:
+ // Check that we do/don't have the extra path argument.
+ if (i==1) {
+ if (toys.optc!=2) help_exit("%s needs a path", name);
+ } else if (toys.optc!=1) help_exit("%s does not take a path", name);
+
+ if (!i) printf("%ld\n", sysconf(c->value));
+ else if (i==1) printf("%ld\n", pathconf(toys.optargs[1], c->value));
+ else if (i==2) {
+ confstr(c->value, toybuf, sizeof(toybuf));
+ puts(toybuf);
+ } else if (i==3) printf("%d\n", c->value);
+ // For legacy kernel build
+ else if (sizeof(long)==4 && !j) {
+ puts("-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64");
}
}
--
2.19.0.605.g01d371f741-goog
enh
2018-10-02 23:21:33 UTC
Reply
Permalink
(in case it's not obvious, this is on top of my other getconf patch
from earlier today.)
Post by enh
Also improve the -l output to include sections (because you need to
know whether you're dealing with a pathconf variable to supply the
required path).
---
toys/posix/getconf.c | 87 +++++++++++++++++++++++++++-----------------
1 file changed, 54 insertions(+), 33 deletions(-)
diff --git a/toys/posix/getconf.c b/toys/posix/getconf.c
index a9ef298..d10365b 100644
--- a/toys/posix/getconf.c
+++ b/toys/posix/getconf.c
@@ -6,17 +6,19 @@
*
* Deviations from posix: no -v because nothing says what it should DO.
-USE_GETCONF(NEWTOY(getconf, "l", TOYFLAG_USR|TOYFLAG_BIN))
+USE_GETCONF(NEWTOY(getconf, ">2l", TOYFLAG_USR|TOYFLAG_BIN))
config GETCONF
bool "getconf"
default y
help
- usage: getconf [-l] [NAME...]
+ usage: getconf -l
+ usage: getconf NAME
+ usage: getconf NAME PATH
- Get system configuration values.
+ Get system configuration values. Values from pathconf(3) require a path.
- -l List available value names
+ -l List available value names (grouped by source)
*/
#define FOR_getconf
@@ -94,6 +96,16 @@ struct config sysconfs[] = {
CONF(NPROCESSORS_ONLN)
};
+// Probe the live system with a path
+struct config pathconfs[] = {
+#undef CONF
+#define CONF(n) {#n,_PC_ ## n}
+ CONF(ASYNC_IO), CONF(CHOWN_RESTRICTED), CONF(FILESIZEBITS), CONF(LINK_MAX),
+ CONF(MAX_CANON), CONF(MAX_INPUT), CONF(NAME_MAX), CONF(NO_TRUNC),
+ CONF(PATH_MAX), CONF(PIPE_BUF), CONF(PRIO_IO), CONF(SYMLINK_MAX),
+ CONF(SYNC_IO), CONF(VDISABLE),
+};
+
// Strings out of a header
struct config confstrs[] = {
#undef CONF
@@ -130,41 +142,50 @@ struct config others[] = {
void getconf_main(void)
{
- struct config *configs[] = {sysconfs, confstrs, limits, others};
- char **args;
- int i, j, lens[] = {ARRAY_LEN(sysconfs), ARRAY_LEN(confstrs),
- ARRAY_LEN(limits), ARRAY_LEN(others)};
+ struct config *configs[] = {sysconfs, pathconfs, confstrs, limits, others},
+ *c = NULL;
+ int i, j, lens[] = {ARRAY_LEN(sysconfs), ARRAY_LEN(pathconfs),
+ ARRAY_LEN(confstrs), ARRAY_LEN(limits), ARRAY_LEN(others)};
+ char *name, *config_names[] = {"sysconf(3)", "pathconf(3)", "confstr(3)",
+ "<limits.h>", "Misc"};
if (toys.optflags&FLAG_l) {
- for (i = 0; i<4; i++) for (j = 0; j<lens[i]; j++) puts(configs[i][j].name);
-
+ for (i = 0; i<5; i++) {
+ printf("%s\n", config_names[i]);
+ for (j = 0; j<lens[i]; j++) {
+ printf(" %s\n", configs[i][j].name);
+ }
+ }
return;
}
- for (args = toys.optargs; *args; args++) {
- char *name = *args;
+ if (toys.optc<1) help_exit(0);
+ name = *toys.optargs;
- // Workaround for autogen using CS_PATH instead of PATH
- if (!strcmp("CS_PATH", name)) name += 3;
+ // Workaround for autogen using CS_PATH instead of PATH
+ if (!strcmp("CS_PATH", name)) name += 3;
- for (i = 0; i<4; i++) for (j = 0; j<lens[i]; j++) {
- struct config *c = &configs[i][j];
-
- if (strcmp(c->name, name)) continue;
-
- if (!i) printf("%ld\n", sysconf(c->value));
- else if (i==1) {
- confstr(c->value, toybuf, sizeof(toybuf));
- puts(toybuf);
- } else if (i==2) printf("%d\n", c->value);
- // For legacy kernel build
- else if (sizeof(long)==4 && !j)
- puts("-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64");
-
- goto cont;
- }
- error_msg("bad '%s'", name);
- ;
+ // Find the config.
+ for (i = 0; i<5; i++) for (j = 0; j<lens[i]; j++) {
+ c = &configs[i][j];
+ if (!strcmp(c->name, name)) goto found;
+ }
+ error_msg("bad '%s'", name);
+
+ // Check that we do/don't have the extra path argument.
+ if (i==1) {
+ if (toys.optc!=2) help_exit("%s needs a path", name);
+ } else if (toys.optc!=1) help_exit("%s does not take a path", name);
+
+ if (!i) printf("%ld\n", sysconf(c->value));
+ else if (i==1) printf("%ld\n", pathconf(toys.optargs[1], c->value));
+ else if (i==2) {
+ confstr(c->value, toybuf, sizeof(toybuf));
+ puts(toybuf);
+ } else if (i==3) printf("%d\n", c->value);
+ // For legacy kernel build
+ else if (sizeof(long)==4 && !j) {
+ puts("-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64");
}
}
--
2.19.0.605.g01d371f741-goog
Rob Landley
2018-10-05 18:18:19 UTC
Reply
Permalink
Post by enh
(in case it's not obvious, this is on top of my other getconf patch
from earlier today.)
Applied, but:

1) getconf -l only outputting symbol names was intentional, it's that whole
"unix way" Mike Gancarz wrote a loely book about. Output that's easily tool
processable, so you can do "for i in $(getconf)" for example. (Toybox produces
just the command names for the same reason.) I understand your motivation for
changing that, but it makes me wince.

2) I missed that upstream has the "-a" option which lists everything, which is
why they don't have a -l. (I don't think ubuntu 14.04 had this, but my test
system died.) We should probably implement that, I might take a stab this weekend.

Rob
enh
2018-10-05 19:41:24 UTC
Reply
Permalink
Post by Rob Landley
Post by enh
(in case it's not obvious, this is on top of my other getconf patch
from earlier today.)
forgot to push?
Post by Rob Landley
1) getconf -l only outputting symbol names was intentional, it's that whole
"unix way" Mike Gancarz wrote a loely book about. Output that's easily tool
processable, so you can do "for i in $(getconf)" for example. (Toybox produces
just the command names for the same reason.) I understand your motivation for
changing that, but it makes me wince.
my motivation was "how else do we explain which ones are pathconf?",
which you need to know because all the others require 0 args, but
pathconf requires 1 arg. it didn't seem reasonable to do that in
--help, and although i considered something like adding '*' to the
pathconf ones, that breaks the traditional unix style that you were
going for but without actually fixing my problem...
Post by Rob Landley
2) I missed that upstream has the "-a" option which lists everything, which is
why they don't have a -l. (I don't think ubuntu 14.04 had this, but my test
system died.) We should probably implement that, I might take a stab this weekend.
not _everything_ --- just the ones that are defined (and i'm guessing
it uses '.' for the pathconf ones?).

but i can do that while you do something more useful :-) i'll fix the
"undefined" behavior too, since i found one caller that was expecting
it... (but i'll wait for you to push first, in case you'd made
additional changes.)
Post by Rob Landley
Rob
enh
2018-10-05 19:42:57 UTC
Reply
Permalink
Post by enh
Post by Rob Landley
Post by enh
(in case it's not obvious, this is on top of my other getconf patch
from earlier today.)
forgot to push?
Post by Rob Landley
1) getconf -l only outputting symbol names was intentional, it's that whole
"unix way" Mike Gancarz wrote a loely book about. Output that's easily tool
processable, so you can do "for i in $(getconf)" for example. (Toybox produces
just the command names for the same reason.) I understand your motivation for
changing that, but it makes me wince.
my motivation was "how else do we explain which ones are pathconf?", which you need to know because all the others require 0 args, but pathconf requires 1 arg. it didn't seem reasonable to do that in --help, and although i considered something like adding '*' to the pathconf ones, that breaks the traditional unix style that you were going for but without actually fixing my problem...
actually, the other reason why i did what i did was: it points you at
the right documentation for each one. because no documentation for
getconf(1) itself is likely to be very helpful.
Post by enh
Post by Rob Landley
2) I missed that upstream has the "-a" option which lists everything, which is
why they don't have a -l. (I don't think ubuntu 14.04 had this, but my test
system died.) We should probably implement that, I might take a stab this weekend.
not _everything_ --- just the ones that are defined (and i'm guessing it uses '.' for the pathconf ones?).
but i can do that while you do something more useful :-) i'll fix the "undefined" behavior too, since i found one caller that was expecting it... (but i'll wait for you to push first, in case you'd made additional changes.)
Post by Rob Landley
Rob
Rob Landley
2018-10-05 21:45:00 UTC
Reply
Permalink
Post by enh
Post by Rob Landley
Post by enh
(in case it's not obvious, this is on top of my other getconf patch
from earlier today.)
forgot to push?
Yup.
Post by enh
Post by Rob Landley
1) getconf -l only outputting symbol names was intentional, it's that whole
"unix way" Mike Gancarz wrote a loely book about. Output that's easily tool
processable, so you can do "for i in $(getconf)" for example. (Toybox produces
just the command names for the same reason.) I understand your motivation for
changing that, but it makes me wince.
my motivation was "how else do we explain which ones are pathconf?",
which you need to know because all the others require 0 args, but
pathconf requires 1 arg.
The default is "/" if you just go "getconf -a".

Hmmm, but it insists when you specify an argument:

$ getconf FILESIZEBITS
Usage: getconf [-v specification] variable_name [pathname]
getconf -a [pathname]
$ getconf FILESIZEBITS /
64

That's really stupid. (The ubuntu one, I mean.)
Post by enh
it didn't seem reasonable to do that in
--help, and although i considered something like adding '*' to the
pathconf ones, that breaks the traditional unix style that you were
going for but without actually fixing my problem...
Indeed.
Post by enh
Post by Rob Landley
2) I missed that upstream has the "-a" option which lists everything, which is
why they don't have a -l. (I don't think ubuntu 14.04 had this, but my test
system died.) We should probably implement that, I might take a stab this weekend.
not _everything_ --- just the ones that are defined (and i'm guessing
it uses '.' for the pathconf ones?).
Pretty sure it uses /

$ diff -u <(cd /; getconf -a) <(cd /proc; getconf -a)
$ diff -u <(getconf -a /) <(getconf -a /proc) | wc
19 45 742
Post by enh
but i can do that while you do something more useful :-) i'll fix the
"undefined" behavior too, since i found one caller that was expecting
it... (but i'll wait for you to push first, in case you'd made
additional changes.)
I didn't. I dunno what success look like here either. (And too busy at work to
think much about it until now.)
Post by enh
Post by Rob Landley
Rob
Rob
enh
2018-10-05 22:25:50 UTC
Reply
Permalink
Post by Rob Landley
Post by enh
Post by Rob Landley
Post by enh
(in case it's not obvious, this is on top of my other getconf patch
from earlier today.)
forgot to push?
Yup.
Post by enh
Post by Rob Landley
1) getconf -l only outputting symbol names was intentional, it's that whole
"unix way" Mike Gancarz wrote a loely book about. Output that's easily tool
processable, so you can do "for i in $(getconf)" for example. (Toybox produces
just the command names for the same reason.) I understand your motivation for
changing that, but it makes me wince.
my motivation was "how else do we explain which ones are pathconf?",
which you need to know because all the others require 0 args, but
pathconf requires 1 arg.
The default is "/" if you just go "getconf -a".
weird. that seems far less useful than '.'.

(i'm not really sure how `getconf -a` is even useful. looks like it's
meant for interactive use when you don't know what a thing's called.
so you do `getconf -a | grep -i uucp` or whatever.)
Post by Rob Landley
$ getconf FILESIZEBITS
Usage: getconf [-v specification] variable_name [pathname]
getconf -a [pathname]
$ getconf FILESIZEBITS /
64
That's really stupid. (The ubuntu one, I mean.)
Post by enh
it didn't seem reasonable to do that in
--help, and although i considered something like adding '*' to the
pathconf ones, that breaks the traditional unix style that you were
going for but without actually fixing my problem...
Indeed.
Post by enh
Post by Rob Landley
2) I missed that upstream has the "-a" option which lists everything, which is
why they don't have a -l. (I don't think ubuntu 14.04 had this, but my test
system died.) We should probably implement that, I might take a stab this weekend.
not _everything_ --- just the ones that are defined (and i'm guessing
it uses '.' for the pathconf ones?).
Pretty sure it uses /
$ diff -u <(cd /; getconf -a) <(cd /proc; getconf -a)
$ diff -u <(getconf -a /) <(getconf -a /proc) | wc
19 45 742
Post by enh
but i can do that while you do something more useful :-) i'll fix the
"undefined" behavior too, since i found one caller that was expecting
it... (but i'll wait for you to push first, in case you'd made
additional changes.)
I didn't. I dunno what success look like here either. (And too busy at work to
think much about it until now.)
the BSD getconf seems less stupid: `getconf -a` shows you the non-path
stuff, `getconf -a PATH` shows you just the path stuff. sounds
reasonable?
Post by Rob Landley
Post by enh
Post by Rob Landley
Rob
Rob
Rob Landley
2018-10-06 17:20:54 UTC
Reply
Permalink
Post by enh
Post by Rob Landley
Post by enh
Post by Rob Landley
Post by enh
(in case it's not obvious, this is on top of my other getconf patch
from earlier today.)
forgot to push?
Yup.
Post by enh
Post by Rob Landley
1) getconf -l only outputting symbol names was intentional, it's that whole
"unix way" Mike Gancarz wrote a loely book about. Output that's easily tool
processable, so you can do "for i in $(getconf)" for example. (Toybox produces
just the command names for the same reason.) I understand your motivation for
changing that, but it makes me wince.
my motivation was "how else do we explain which ones are pathconf?",
which you need to know because all the others require 0 args, but
pathconf requires 1 arg.
The default is "/" if you just go "getconf -a".
weird. that seems far less useful than '.'.
I think it's trying to give you VFS statistics? (Wild guess. No guarantee /
isn't crazy either, of course.)
Post by enh
(i'm not really sure how `getconf -a` is even useful. looks like it's
meant for interactive use when you don't know what a thing's called.
so you do `getconf -a | grep -i uucp` or whatever.)
Snapshotting a system's stats and comparing with another system, I think. (My
own test case above was diff -u of two outputs.)
Post by enh
Post by Rob Landley
Post by enh
but i can do that while you do something more useful :-) i'll fix the
"undefined" behavior too, since i found one caller that was expecting
it... (but i'll wait for you to push first, in case you'd made
additional changes.)
I didn't. I dunno what success look like here either. (And too busy at work to
think much about it until now.)
the BSD getconf seems less stupid: `getconf -a` shows you the non-path
stuff, `getconf -a PATH` shows you just the path stuff. sounds
reasonable?
*shrug* I'm happy to be led here.

My motivation for adding this was builds (mainly the kernel build but there were
others) complaining about a lack of getconf. Beyond that I haven't got a test
case, I just objected to the first contribution I got here having no way to list
the keys it supported...

Rob
enh
2018-10-24 21:34:21 UTC
Reply
Permalink
Post by Rob Landley
Post by enh
Post by Rob Landley
Post by enh
Post by Rob Landley
Post by enh
(in case it's not obvious, this is on top of my other getconf patch
from earlier today.)
forgot to push?
Yup.
Post by enh
Post by Rob Landley
1) getconf -l only outputting symbol names was intentional, it's that whole
"unix way" Mike Gancarz wrote a loely book about. Output that's easily tool
processable, so you can do "for i in $(getconf)" for example. (Toybox produces
just the command names for the same reason.) I understand your motivation for
changing that, but it makes me wince.
my motivation was "how else do we explain which ones are pathconf?",
which you need to know because all the others require 0 args, but
pathconf requires 1 arg.
The default is "/" if you just go "getconf -a".
weird. that seems far less useful than '.'.
I think it's trying to give you VFS statistics? (Wild guess. No guarantee /
isn't crazy either, of course.)
Post by enh
(i'm not really sure how `getconf -a` is even useful. looks like it's
meant for interactive use when you don't know what a thing's called.
so you do `getconf -a | grep -i uucp` or whatever.)
Snapshotting a system's stats and comparing with another system, I think. (My
own test case above was diff -u of two outputs.)
Post by enh
Post by Rob Landley
Post by enh
but i can do that while you do something more useful :-) i'll fix the
"undefined" behavior too, since i found one caller that was expecting
it... (but i'll wait for you to push first, in case you'd made
additional changes.)
I didn't. I dunno what success look like here either. (And too busy at work to
think much about it until now.)
the BSD getconf seems less stupid: `getconf -a` shows you the non-path
stuff, `getconf -a PATH` shows you just the path stuff. sounds
reasonable?
*shrug* I'm happy to be led here.
since i don't really care either, i've sent you patch that copies the
FSF behavior of assuming "/" if no path is supplied. i personally
think the BSD behavior is more sensible, but since we _are_ aiming to
replace various Linux tools not _aren't_ targeting BSD, i'm assuming
that the FSF behavior is more likely to be useful to our target
audience.
Post by Rob Landley
My motivation for adding this was builds (mainly the kernel build but there were
others) complaining about a lack of getconf. Beyond that I haven't got a test
case, I just objected to the first contribution I got here having no way to list
the keys it supported...
Rob
Loading...