https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=8e3e5a784f302d59f0edcb305a3650e3e404391a

commit 8e3e5a784f302d59f0edcb305a3650e3e404391a
Author:     Corinna Vinschen <[email protected]>
AuthorDate: Fri Dec 5 20:30:26 2025 +0100
Commit:     Corinna Vinschen <[email protected]>
CommitDate: Wed Dec 10 18:08:28 2025 +0100

    Cygwin: newgrp(1): improve POSIX compatibility
    
    - allow calling without argument
    - allow not only - but also -l to regenerate stock environment
    - allow numerical group IDs
    - In usage output, advertise -l instead of - and do not advertise
      the ability to run an arbitrary command instead of just a new shell
    
    Signed-off-by: Corinna Vinschen <[email protected]>

Diff:
---
 winsup/utils/newgrp.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/winsup/utils/newgrp.c b/winsup/utils/newgrp.c
index 414e8cdf8edc..25cdd842da02 100644
--- a/winsup/utils/newgrp.c
+++ b/winsup/utils/newgrp.c
@@ -140,16 +140,18 @@ main (int argc, const char **argv)
 
   setlocale (LC_ALL, "");
 
-  if (argc < 2 || (argv[1][0] == '-' && argv[1][1]))
-    {
-      fprintf (stderr, "Usage: %s [-] [group] [command [args...]]\n",
-              program_invocation_short_name);
-      return 1;
-    }
-
   /* Check if we have to regenerate a stock environment */
-  if (argv[1][0] == '-')
+  if (argc > 1 && argv[1][0] == '-')
     {
+      if (argv[1][1] != '\0' && strcmp (argv[1], "-l") != 0)
+       {
+         /* Advertise POSIX compatibility in the first place.  Do not
+            advertise the single dash as valid option (per Linux) and
+            do not advertise the ability to run an arbitrary command. */
+         fprintf (stderr, "Usage: %s [-l] [group]\n",
+                  program_invocation_short_name);
+         return 1;
+       }
       new_child_env = true;
       --argc;
       ++argv;
@@ -165,8 +167,16 @@ main (int argc, const char **argv)
     }
   else
     {
-      gr = getgrnam (argv[1]);
-      if (!gr)
+      char *eptr;
+
+      if ((gr = getgrnam (argv[1])) != NULL)
+       /*valid*/;
+      else if (isdigit ((int) argv[1][0])
+              && (gid = strtoul (argv[1], &eptr, 10)) != ULONG_MAX
+              && *eptr == '\0'
+              && (gr = getgrgid (gid)) != NULL)
+       /*valid*/;
+      else
        {
          fprintf (stderr, "%s: group '%s' does not exist\n",
                   program_invocation_short_name, argv[1]);

Reply via email to