From: Gábor Németh Date: Thu, 29 Aug 2024 06:59:23 +0000 (+0200) Subject: Optionally execute a program after group change X-Git-Tag: v2.42-start~213^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3b7aeba581e4421f25b9a739c43eb5fe3bdb31be;p=thirdparty%2Futil-linux.git Optionally execute a program after group change We accept a `-c` command option or possible second argument which is then invoked through the user's shell after the group change, as by the `sg` utility. The default is still running the shell itself. --- diff --git a/bash-completion/newgrp b/bash-completion/newgrp index 1e39c0f42..c6d678b93 100644 --- a/bash-completion/newgrp +++ b/bash-completion/newgrp @@ -8,15 +8,23 @@ _newgrp_module() '-h'|'--help'|'-V'|'--version') return 0 ;; + '-c'|'--command') + COMPREPLY=( $(compgen -c -- $cur) ) + return 0 + ;; esac case $cur in -*) - OPTS="--version --help" + OPTS="--version --help --command" COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) ) return 0 ;; esac - COMPREPLY=( $(compgen -g -- $cur) ) + if (( COMP_CWORD == 1 )) || [[ " ${COMP_WORDS[@]}" =~ " "-?-c ]]; then + COMPREPLY=( $(compgen -g -- $cur) ) + else + COMPREPLY=( $(compgen -c -- $cur) ) + fi return 0 } complete -F _newgrp_module newgrp diff --git a/login-utils/newgrp.1.adoc b/login-utils/newgrp.1.adoc index e9a90d3ea..521b73559 100644 --- a/login-utils/newgrp.1.adoc +++ b/login-utils/newgrp.1.adoc @@ -18,7 +18,9 @@ newgrp - log in to a new group == SYNOPSIS -*newgrp* [_group_] +*newgrp* [_group_ [_command_]] + +*newgrp* [*-c* _command_] [_group_] == DESCRIPTION @@ -26,8 +28,13 @@ newgrp - log in to a new group If no group is specified, the GID is changed to the login GID. +An optional command can be specified, which is invoked after group change instead of the user's shell. + == OPTIONS +*-c*, *--command*=__command__:: +Pass _command_ to the user's shell with the *-c* option. + include::man-common/help-version.adoc[] == FILES diff --git a/login-utils/newgrp.c b/login-utils/newgrp.c index e71a9e134..b9b620ed7 100644 --- a/login-utils/newgrp.c +++ b/login-utils/newgrp.c @@ -172,10 +172,10 @@ static void __attribute__((__noreturn__)) usage(void) { FILE *out = stdout; fputs(USAGE_HEADER, out); - fprintf(out, _(" %s \n"), program_invocation_short_name); + fprintf(out, _(" %s [[-c] ]\n"), program_invocation_short_name); fputs(USAGE_SEPARATOR, out); - fputs(_("Log in to a new group.\n"), out); + fputs(_("Log in to a new group; optionally executing a shell command.\n"), out); fputs(USAGE_OPTIONS, out); fprintf(out, USAGE_HELP_OPTIONS(16)); @@ -187,11 +187,12 @@ int main(int argc, char *argv[]) { struct passwd *pw_entry; struct group *gr_entry; - char *shell; + char *shell, *command = NULL; int ch; static const struct option longopts[] = { {"version", no_argument, NULL, 'V'}, {"help", no_argument, NULL, 'h'}, + {"command", required_argument, NULL, 'c'}, {NULL, 0, NULL, 0} }; @@ -200,8 +201,11 @@ int main(int argc, char *argv[]) textdomain(PACKAGE); close_stdout_atexit(); - while ((ch = getopt_long(argc, argv, "Vh", longopts, NULL)) != -1) + while ((ch = getopt_long(argc, argv, "c:Vh", longopts, NULL)) != -1) switch (ch) { + case 'c': + command = optarg; + break; case 'V': print_version(EXIT_SUCCESS); case 'h': @@ -213,12 +217,12 @@ int main(int argc, char *argv[]) if (!(pw_entry = getpwuid(getuid()))) err(EXIT_FAILURE, _("who are you?")); - if (argc < 2) { + if (argc <= optind) { if (setgid(pw_entry->pw_gid) < 0) err(EXIT_FAILURE, _("setgid failed")); } else { errno = 0; - if (!(gr_entry = getgrnam(argv[1]))) { + if (!(gr_entry = getgrnam(argv[optind++]))) { if (errno) err(EXIT_FAILURE, _("no such group")); else @@ -236,6 +240,8 @@ int main(int argc, char *argv[]) fflush(NULL); shell = (pw_entry->pw_shell && *pw_entry->pw_shell ? pw_entry->pw_shell : _PATH_BSHELL); - execl(shell, shell, (char *)NULL); + if (!command && optind < argc) + command = argv[optind]; + execl(shell, shell, command ? "-c" : NULL, command, (char *)NULL); errexec(shell); }