diff options
author | Bernhard Voelker <mail@bernhard-voelker.de> | 2013-09-21 14:15:45 +0200 |
---|---|---|
committer | Bernhard Voelker <mail@bernhard-voelker.de> | 2013-09-21 14:15:45 +0200 |
commit | 2a0d241f69f7f3f5b826656a97f9bafb20bd8711 (patch) | |
tree | 3e23194ad9215ceee6f4f6cb2158b4f925318ea3 /src | |
parent | b3578fc9ffe70b9466687f9f6470a85f1a0ab14f (diff) | |
download | coreutils-2a0d241f69f7f3f5b826656a97f9bafb20bd8711.tar.xz |
id: add -z, --zero option
* src/group-list.h (print_group_list): Add a parameter for the
delimiter of type char.
* src/group-list.c (print_group_list): Likewise, and use it instead
of a white space character to delimit the group entries.
* src/groups.c (main): Pass white space character to print_group_list().
* src/id.c (longopts): Add array element for the new long option.
(usage): Document the new option. While at it, fix the alignment
of the descriptions to match that of HELP_OPTION_DESCRIPTION.
(main): Define the bool flag opt_zero indicating the use of the
new option. In the getopt_long loop, handle it.
Output an error diagnostic in the case the --zero option has been
specified together with the default format.
In the case of -gG, pass either a NUL or a white space character to
print_group_list() - depending on the above new flag.
Likewise change the printing of the final newline character: output
a NUL instead if the --zero option has been specified.
* doc/coreutils.texi (id invocation): Document the new option.
While at it, move the @exitstatus macro down after the macro
@primaryAndSupplementaryGroups in order to be consistent with
other texinfo documents.
(groups invocation): Move @exitstatus down after the macro
@primaryAndSupplementaryGroups here, too.
* tests/misc/id-zero.sh: Add new test exercising the new option.
* tests/local.mk (all_tests): Reference it.
* NEWS (New features): Mention the new option.
Fixes http://bugs.gnu.org/9987
Diffstat (limited to 'src')
-rw-r--r-- | src/group-list.c | 6 | ||||
-rw-r--r-- | src/group-list.h | 2 | ||||
-rw-r--r-- | src/groups.c | 6 | ||||
-rw-r--r-- | src/id.c | 36 |
4 files changed, 32 insertions, 18 deletions
diff --git a/src/group-list.c b/src/group-list.c index 7d4995b5c..d54b05776 100644 --- a/src/group-list.c +++ b/src/group-list.c @@ -35,7 +35,7 @@ extern bool print_group_list (const char *username, uid_t ruid, gid_t rgid, gid_t egid, - bool use_names) + bool use_names, char delim) { bool ok = true; struct passwd *pwd = NULL; @@ -52,7 +52,7 @@ print_group_list (const char *username, if (egid != rgid) { - putchar (' '); + putchar (delim); if (!print_group (egid, use_names)) ok = false; } @@ -79,7 +79,7 @@ print_group_list (const char *username, for (i = 0; i < n_groups; i++) if (groups[i] != rgid && groups[i] != egid) { - putchar (' '); + putchar (delim); if (!print_group (groups[i], use_names)) ok = false; } diff --git a/src/group-list.h b/src/group-list.h index 3fac88719..573de1def 100644 --- a/src/group-list.h +++ b/src/group-list.h @@ -16,4 +16,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ bool print_group (gid_t, bool); -bool print_group_list (const char *, uid_t, gid_t, gid_t, bool); +bool print_group_list (const char *, uid_t, gid_t, gid_t, bool, char); diff --git a/src/groups.c b/src/groups.c index 53332d56b..d30c9fb41 100644 --- a/src/groups.c +++ b/src/groups.c @@ -114,13 +114,13 @@ main (int argc, char **argv) if (rgid == NO_GID && errno) error (EXIT_FAILURE, errno, _("cannot get real GID")); - if (!print_group_list (NULL, ruid, rgid, egid, true)) + if (!print_group_list (NULL, ruid, rgid, egid, true, ' ')) ok = false; putchar ('\n'); } else { - /* At least one argument. Divulge the details of the specified users. */ + /* At least one argument. Divulge the details of the specified users. */ while (optind < argc) { struct passwd *pwd = getpwnam (argv[optind]); @@ -130,7 +130,7 @@ main (int argc, char **argv) rgid = egid = pwd->pw_gid; printf ("%s : ", argv[optind]); - if (!print_group_list (argv[optind++], ruid, rgid, egid, true)) + if (!print_group_list (argv[optind++], ruid, rgid, egid, true, ' ')) ok = false; putchar ('\n'); } @@ -67,6 +67,7 @@ static struct option const longopts[] = {"name", no_argument, NULL, 'n'}, {"real", no_argument, NULL, 'r'}, {"user", no_argument, NULL, 'u'}, + {"zero", no_argument, NULL, 'z'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} @@ -83,14 +84,18 @@ usage (int status) fputs (_("\ Print user and group information for the specified USERNAME,\n\ or (when USERNAME omitted) for the current user.\n\ -\n\ - -a ignore, for compatibility with other versions\n\ - -Z, --context print only the security context of the current user\n\ - -g, --group print only the effective group ID\n\ - -G, --groups print all group IDs\n\ - -n, --name print a name instead of a number, for -ugG\n\ - -r, --real print the real ID instead of the effective ID, with -ugG\n\ - -u, --user print only the effective user ID\n\ +\n"), + stdout); + fputs (_("\ + -a ignore, for compatibility with other versions\n\ + -Z, --context print only the security context of the current user\n\ + -g, --group print only the effective group ID\n\ + -G, --groups print all group IDs\n\ + -n, --name print a name instead of a number, for -ugG\n\ + -r, --real print the real ID instead of the effective ID, with -ugG\n\ + -u, --user print only the effective user ID\n\ + -z, --zero delimit entries with NUL characters, not whitespace;\n\ + not permitted in default format\n\ "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); @@ -109,6 +114,7 @@ main (int argc, char **argv) int optc; int selinux_enabled = (is_selinux_enabled () > 0); bool smack_enabled = is_smack_enabled (); + bool opt_zero = false; /* If true, output the list of all group IDs. -G */ bool just_group_list = false; @@ -127,7 +133,7 @@ main (int argc, char **argv) atexit (close_stdout); - while ((optc = getopt_long (argc, argv, "agnruGZ", longopts, NULL)) != -1) + while ((optc = getopt_long (argc, argv, "agnruzGZ", longopts, NULL)) != -1) { switch (optc) { @@ -162,6 +168,9 @@ main (int argc, char **argv) case 'u': just_user = true; break; + case 'z': + opt_zero = true; + break; case 'G': just_group_list = true; break; @@ -193,6 +202,10 @@ main (int argc, char **argv) error (EXIT_FAILURE, 0, _("cannot print only names or real IDs in default format")); + if (default_format && opt_zero) + error (EXIT_FAILURE, 0, + _("option --zero not permitted in default format")); + /* If we are on a SELinux/SMACK-enabled kernel, no user is specified, and either --context is specified or none of (-u,-g,-G) is specified, and we're not in POSIXLY_CORRECT mode, get our context. Otherwise, @@ -269,7 +282,8 @@ main (int argc, char **argv) } else if (just_group_list) { - if (!print_group_list (argv[optind], ruid, rgid, egid, use_name)) + if (!print_group_list (argv[optind], ruid, rgid, egid, use_name, + opt_zero ? '\0' : ' ')) ok = false; } else if (just_context) @@ -280,7 +294,7 @@ main (int argc, char **argv) { print_full_info (argv[optind]); } - putchar ('\n'); + putchar (opt_zero ? '\0' : '\n'); exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); } |