summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBernhard Voelker <mail@bernhard-voelker.de>2013-09-21 14:15:45 +0200
committerBernhard Voelker <mail@bernhard-voelker.de>2013-09-21 14:15:45 +0200
commit2a0d241f69f7f3f5b826656a97f9bafb20bd8711 (patch)
tree3e23194ad9215ceee6f4f6cb2158b4f925318ea3 /src
parentb3578fc9ffe70b9466687f9f6470a85f1a0ab14f (diff)
downloadcoreutils-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.c6
-rw-r--r--src/group-list.h2
-rw-r--r--src/groups.c6
-rw-r--r--src/id.c36
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');
}
diff --git a/src/id.c b/src/id.c
index 3e7016f7b..a0334ba73 100644
--- a/src/id.c
+++ b/src/id.c
@@ -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);
}