Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib/, src/: Simplify code that calls [sg]etgroups(3) #1123

Open
wants to merge 23 commits into
base: master
Choose a base branch
from

Conversation

alejandro-colomar
Copy link
Collaborator

@alejandro-colomar alejandro-colomar commented Nov 14, 2024

Queued after #1093


Revisions:

v2
  • Avoid double evaluation in macro LFIND(). [@uecker]
  • Make return type match typeof($1). [@uecker]
$ git range-diff strsep gh/add_groups add_groups 
1:  9615bacf = 1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
2:  e6069988 = 2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
3:  c592e66a = 3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
4:  a78be8a3 = 4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
5:  35341fd7 = 5:  35341fd7 lib/: cmp_long(): Move and rename function
6:  881ea430 ! 6:  3e000527 lib/search/lfind/: LFIND(): Add macro
    @@ lib/search/lfind/lfind.h (new)
     +#include <stddef.h>
     +
     +
    -+#define LFIND(k, a, n, cmp)                                                   \
    -+(                                                                             \
    -+  _Generic(*(k), typeof((a)[0]): lfind_(k, a, n, sizeof(*(k)), cmp))    \
    -+)
    ++#define LFIND(k, a, n, cmp)                                           \
    ++({                                                                    \
    ++  __auto_type  k_ = k;                                          \
    ++  __auto_type  a_ = a;                                          \
    ++                                                                      \
    ++  static_assert(is_same_typeof(k_, a_), "");                    \
    ++                                                                      \
    ++  (typeof(k_)) lfind_(k_, a_, n, sizeof(*k_), cmp);             \
    ++})
     +
     +
     +inline void *lfind_(const void *k, const void *a, size_t n, size_t ksize,
7:  94125e40 = 7:  430827d1 lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
v2b
  • Add missing includes.
$ git range-diff strsep gh/add_groups add_groups 
1:  9615bacf = 1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
2:  e6069988 = 2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
3:  c592e66a = 3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
4:  a78be8a3 = 4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
5:  35341fd7 = 5:  35341fd7 lib/: cmp_long(): Move and rename function
6:  3e000527 ! 6:  63395399 lib/search/lfind/: LFIND(): Add macro
    @@ lib/search/lfind/lfind.h (new)
     +#include <search.h>
     +#include <stddef.h>
     +
    ++#include "must_be.h"
    ++
    ++#include <assert.h>
    ++
     +
     +#define LFIND(k, a, n, cmp)                                           \
     +({                                                                    \
7:  430827d1 = 7:  d64c8a96 lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
v2c
  • Add Co-authored-by tag [@uecker ]
$ git range-diff strsep gh/add_groups add_groups 
1:  9615bacf = 1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
2:  e6069988 = 2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
3:  c592e66a = 3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
4:  a78be8a3 = 4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
5:  35341fd7 = 5:  35341fd7 lib/: cmp_long(): Move and rename function
6:  63395399 ! 6:  095f8869 lib/search/lfind/: LFIND(): Add macro
    @@ Metadata
      ## Commit message ##
         lib/search/lfind/: LFIND(): Add macro
     
    +    Co-authored-by: Martin Uecker <[email protected]>
         Signed-off-by: Alejandro Colomar <[email protected]>
     
      ## lib/Makefile.am ##
7:  d64c8a96 = 7:  b7b50b7f lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
v3
  • Use lsearch(3) (through a LSEARCH() new wrapper) instead of its pattern.
  • Improve error handling.
  • Further simplification of add_groups().
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  a78be8a3 =  4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
 5:  35341fd7 =  5:  35341fd7 lib/: cmp_long(): Move and rename function
 6:  095f8869 !  6:  50c01c13 lib/search/lfind/: LFIND(): Add macro
    @@ Metadata
     Author: Alejandro Colomar <[email protected]>
     
      ## Commit message ##
    -    lib/search/lfind/: LFIND(): Add macro
    +    lib/search/l/: LFIND(): Add macro
     
         Co-authored-by: Martin Uecker <[email protected]>
         Signed-off-by: Alejandro Colomar <[email protected]>
    @@ lib/Makefile.am: libshadow_la_SOURCES = \
        search/cmp/cmp_gid.h \
        search/cmp/cmp_long.c \
        search/cmp/cmp_long.h \
    -+  search/lfind/lfind.c \
    -+  search/lfind/lfind.h \
    ++  search/l/lfind.c \
    ++  search/l/lfind.h \
        selinux.c \
        semanage.c \
        setugid.c \
     
    - ## lib/search/lfind/lfind.c (new) ##
    + ## lib/search/l/lfind.c (new) ##
     @@
     +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <[email protected]>
     +// SPDX-License-Identifier: BSD-3-Clause
    @@ lib/search/lfind/lfind.c (new)
     +
     +#include <config.h>
     +
    -+#include "search/lfind/lfind.h"
    ++#include "search/l/lfind.h"
     +
     +#include <stddef.h>
     +
    @@ lib/search/lfind/lfind.c (new)
     +extern inline void *lfind_(const void *k, const void *a, size_t n, size_t ksize,
     +    int (*cmp)(const void *k, const void *elt));
     
    - ## lib/search/lfind/lfind.h (new) ##
    + ## lib/search/l/lfind.h (new) ##
     @@
     +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <[email protected]>
     +// SPDX-License-Identifier: BSD-3-Clause
     +
     +
    -+#ifndef SHADOW_INCLUDE_LIB_SEARCH_LFIND_LFIND_H_
    -+#define SHADOW_INCLUDE_LIB_SEARCH_LFIND_LFIND_H_
    ++#ifndef SHADOW_INCLUDE_LIB_SEARCH_L_LFIND_H_
    ++#define SHADOW_INCLUDE_LIB_SEARCH_L_LFIND_H_
     +
     +
     +#include <config.h>
 7:  b7b50b7f !  7:  f472749b lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
    @@ lib/addgrps.c
      #include "alloc/malloc.h"
      #include "alloc/reallocf.h"
     +#include "search/cmp/cmp_gid.h"
    -+#include "search/lfind/lfind.h"
    ++#include "search/l/lfind.h"
      #include "shadowlog.h"
      
      #ident "$Id$"
 -:  -------- >  8:  3f5a9620 lib/addgrps.c: add_groups(): Remove useless cast
 -:  -------- >  9:  d13b47db lib/addgrps.c: add_groups(): Allocate earlier
 -:  -------- > 10:  456f7215 lib/search/l/: LSEARCH(): Add macro
 -:  -------- > 11:  71af013e lib/addgrps.c: add_groups(): Simplify redundant code with a goto
 -:  -------- > 12:  04dc0fa3 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
 -:  -------- > 13:  35b4ae9e lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
 -:  -------- > 14:  b2a475b9 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
 -:  -------- > 15:  6056e8ec lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
v3b
  • wsfix
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  a78be8a3 =  4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
 5:  35341fd7 =  5:  35341fd7 lib/: cmp_long(): Move and rename function
 6:  50c01c13 =  6:  50c01c13 lib/search/l/: LFIND(): Add macro
 7:  f472749b =  7:  f472749b lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  3f5a9620 =  8:  3f5a9620 lib/addgrps.c: add_groups(): Remove useless cast
 9:  d13b47db =  9:  d13b47db lib/addgrps.c: add_groups(): Allocate earlier
10:  456f7215 ! 10:  af6903a6 lib/search/l/: LSEARCH(): Add macro
    @@ lib/search/l/lsearch.h (new)
     +#include <assert.h>
     +
     +
    -+#define LSEARCH(k, a, n, cmp)                                           \
    ++#define LSEARCH(k, a, n, cmp)                                         \
     +({                                                                    \
     +  __auto_type  k_ = k;                                          \
     +  __auto_type  a_ = a;                                          \
11:  71af013e = 11:  b98586af lib/addgrps.c: add_groups(): Simplify redundant code with a goto
12:  04dc0fa3 = 12:  53a15822 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
13:  35b4ae9e = 13:  86cf3448 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  b2a475b9 = 14:  509fff81 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
15:  6056e8ec = 15:  53b8360e lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
v4
  • Allocate at once, instead of +1 in a loop.
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  a78be8a3 =  4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
 5:  35341fd7 =  5:  35341fd7 lib/: cmp_long(): Move and rename function
 6:  50c01c13 =  6:  50c01c13 lib/search/l/: LFIND(): Add macro
 7:  f472749b =  7:  f472749b lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  3f5a9620 =  8:  3f5a9620 lib/addgrps.c: add_groups(): Remove useless cast
 9:  d13b47db =  9:  d13b47db lib/addgrps.c: add_groups(): Allocate earlier
10:  af6903a6 = 10:  af6903a6 lib/search/l/: LSEARCH(): Add macro
11:  b98586af = 11:  b98586af lib/addgrps.c: add_groups(): Simplify redundant code with a goto
12:  53a15822 = 12:  53a15822 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
13:  86cf3448 = 13:  86cf3448 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  509fff81 = 14:  509fff81 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
15:  53b8360e = 15:  53b8360e lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
 -:  -------- > 16:  9213a1ee lib/string/strchr/: strchrscnt(): Add function
 -:  -------- > 17:  a385d319 lib/addgrps.c: add_groups(): Reallocate at once
v4b
  • tfix
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  a78be8a3 =  4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
 5:  35341fd7 =  5:  35341fd7 lib/: cmp_long(): Move and rename function
 6:  50c01c13 =  6:  50c01c13 lib/search/l/: LFIND(): Add macro
 7:  f472749b =  7:  f472749b lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  3f5a9620 =  8:  3f5a9620 lib/addgrps.c: add_groups(): Remove useless cast
 9:  d13b47db =  9:  d13b47db lib/addgrps.c: add_groups(): Allocate earlier
10:  af6903a6 = 10:  af6903a6 lib/search/l/: LSEARCH(): Add macro
11:  b98586af = 11:  b98586af lib/addgrps.c: add_groups(): Simplify redundant code with a goto
12:  53a15822 = 12:  53a15822 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
13:  86cf3448 = 13:  86cf3448 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  509fff81 ! 14:  241962df lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
    @@ lib/addgrps.c: add_groups(const char *list)
      
     -  if (setgroups(ngroups, grouplist) == -1)
     +  if (setgroups(ngroups, grouplist) == -1) {
    -+          fprintf(shadow_logfd, _("Error: setgroups: %s\n", strerror(errno)));
    ++          fprintf(shadow_logfd, _("Error: setgroups: %s\n"), strerror(errno));
                goto fail;
     +  }
      
15:  53b8360e ! 15:  124b0628 lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
    @@ lib/addgrps.c: add_groups(const char *list)
      
     -  if (setgroups(ngroups, grouplist) == -1) {
     +  if (setgroups(n, grouplist) == -1) {
    -           fprintf(shadow_logfd, _("Error: setgroups: %s\n", strerror(errno)));
    +           fprintf(shadow_logfd, _("Error: setgroups: %s\n"), strerror(errno));
                goto fail;
        }
16:  9213a1ee = 16:  ccc7d399 lib/string/strchr/: strchrscnt(): Add function
17:  a385d319 = 17:  eb9e15b3 lib/addgrps.c: add_groups(): Reallocate at once
v4c
  • tfix
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  a78be8a3 =  4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
 5:  35341fd7 =  5:  35341fd7 lib/: cmp_long(): Move and rename function
 6:  50c01c13 =  6:  50c01c13 lib/search/l/: LFIND(): Add macro
 7:  f472749b =  7:  f472749b lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  3f5a9620 =  8:  3f5a9620 lib/addgrps.c: add_groups(): Remove useless cast
 9:  d13b47db =  9:  d13b47db lib/addgrps.c: add_groups(): Allocate earlier
10:  af6903a6 = 10:  af6903a6 lib/search/l/: LSEARCH(): Add macro
11:  b98586af = 11:  b98586af lib/addgrps.c: add_groups(): Simplify redundant code with a goto
12:  53a15822 = 12:  53a15822 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
13:  86cf3448 = 13:  86cf3448 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  241962df = 14:  241962df lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
15:  124b0628 = 15:  124b0628 lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
16:  ccc7d399 = 16:  ccc7d399 lib/string/strchr/: strchrscnt(): Add function
17:  eb9e15b3 ! 17:  b3f3fff6 lib/addgrps.c: add_groups(): Reallocate at once
    @@ lib/addgrps.c
      #include "shadowlog.h"
     -
     -#ident "$Id$"
    -+#include "string/strchr/strchrscnt/h"
    ++#include "string/strchr/strchrscnt.h"
      
      
      /*
v4d
  • Add missing include
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  a78be8a3 =  4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
 5:  35341fd7 =  5:  35341fd7 lib/: cmp_long(): Move and rename function
 6:  50c01c13 =  6:  50c01c13 lib/search/l/: LFIND(): Add macro
 7:  f472749b =  7:  f472749b lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  3f5a9620 =  8:  3f5a9620 lib/addgrps.c: add_groups(): Remove useless cast
 9:  d13b47db =  9:  d13b47db lib/addgrps.c: add_groups(): Allocate earlier
10:  af6903a6 = 10:  af6903a6 lib/search/l/: LSEARCH(): Add macro
11:  b98586af = 11:  b98586af lib/addgrps.c: add_groups(): Simplify redundant code with a goto
12:  53a15822 = 12:  53a15822 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
13:  86cf3448 = 13:  86cf3448 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  241962df = 14:  241962df lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
15:  124b0628 = 15:  124b0628 lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
16:  ccc7d399 ! 16:  2aa4579f lib/string/strchr/: strchrscnt(): Add function
    @@ lib/string/strchr/strchrscnt.h (new)
     +#include <stddef.h>
     +
     +#include "attr.h"
    ++#include "string/strchr/strchrcnt.h"
     +#include "string/strcmp/streq.h"
     +
     +
17:  b3f3fff6 = 17:  96da32c1 lib/addgrps.c: add_groups(): Reallocate at once
v4e
  • Simplify error message.
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  a78be8a3 =  4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
 5:  35341fd7 =  5:  35341fd7 lib/: cmp_long(): Move and rename function
 6:  50c01c13 =  6:  50c01c13 lib/search/l/: LFIND(): Add macro
 7:  f472749b =  7:  f472749b lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  3f5a9620 =  8:  3f5a9620 lib/addgrps.c: add_groups(): Remove useless cast
 9:  d13b47db =  9:  d13b47db lib/addgrps.c: add_groups(): Allocate earlier
10:  af6903a6 = 10:  af6903a6 lib/search/l/: LSEARCH(): Add macro
11:  b98586af = 11:  b98586af lib/addgrps.c: add_groups(): Simplify redundant code with a goto
12:  53a15822 = 12:  53a15822 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
13:  86cf3448 = 13:  86cf3448 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  241962df ! 14:  d38984cd lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
    @@ lib/addgrps.c: add_groups(const char *list)
      
     -  if (setgroups(ngroups, grouplist) == -1)
     +  if (setgroups(ngroups, grouplist) == -1) {
    -+          fprintf(shadow_logfd, _("Error: setgroups: %s\n"), strerror(errno));
    ++          fprintf(shadow_logfd, _("setgroups: %s\n"), strerror(errno));
                goto fail;
     +  }
      
15:  124b0628 ! 15:  5cc8fff7 lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
    @@ lib/addgrps.c: add_groups(const char *list)
      
     -  if (setgroups(ngroups, grouplist) == -1) {
     +  if (setgroups(n, grouplist) == -1) {
    -           fprintf(shadow_logfd, _("Error: setgroups: %s\n"), strerror(errno));
    +           fprintf(shadow_logfd, _("setgroups: %s\n"), strerror(errno));
                goto fail;
        }
16:  2aa4579f = 16:  d77fdaee lib/string/strchr/: strchrscnt(): Add function
17:  96da32c1 = 17:  29ac6014 lib/addgrps.c: add_groups(): Reallocate at once
v4f
  • There's nothign to translate anymore.
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  a78be8a3 =  4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
 5:  35341fd7 =  5:  35341fd7 lib/: cmp_long(): Move and rename function
 6:  50c01c13 =  6:  50c01c13 lib/search/l/: LFIND(): Add macro
 7:  f472749b =  7:  f472749b lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  3f5a9620 =  8:  3f5a9620 lib/addgrps.c: add_groups(): Remove useless cast
 9:  d13b47db =  9:  d13b47db lib/addgrps.c: add_groups(): Allocate earlier
10:  af6903a6 = 10:  af6903a6 lib/search/l/: LSEARCH(): Add macro
11:  b98586af = 11:  b98586af lib/addgrps.c: add_groups(): Simplify redundant code with a goto
12:  53a15822 = 12:  53a15822 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
13:  86cf3448 = 13:  86cf3448 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  d38984cd ! 14:  f5543414 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
    @@ lib/addgrps.c: add_groups(const char *list)
      
     -  if (setgroups(ngroups, grouplist) == -1)
     +  if (setgroups(ngroups, grouplist) == -1) {
    -+          fprintf(shadow_logfd, _("setgroups: %s\n"), strerror(errno));
    ++          fprintf(shadow_logfd, "setgroups: %s\n", strerror(errno));
                goto fail;
     +  }
      
15:  5cc8fff7 ! 15:  c0f2d3aa lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
    @@ lib/addgrps.c: add_groups(const char *list)
      
     -  if (setgroups(ngroups, grouplist) == -1) {
     +  if (setgroups(n, grouplist) == -1) {
    -           fprintf(shadow_logfd, _("setgroups: %s\n"), strerror(errno));
    +           fprintf(shadow_logfd, "setgroups: %s\n", strerror(errno));
                goto fail;
        }
16:  d77fdaee = 16:  8dd9817c lib/string/strchr/: strchrscnt(): Add function
17:  29ac6014 = 17:  41ee16cc lib/addgrps.c: add_groups(): Reallocate at once
v5
  • Automatically detect the right comparison function.
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  a78be8a3 =  4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
 5:  35341fd7 =  5:  35341fd7 lib/: cmp_long(): Move and rename function
 6:  50c01c13 =  6:  50c01c13 lib/search/l/: LFIND(): Add macro
 7:  f472749b =  7:  f472749b lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  3f5a9620 =  8:  3f5a9620 lib/addgrps.c: add_groups(): Remove useless cast
 9:  d13b47db =  9:  d13b47db lib/addgrps.c: add_groups(): Allocate earlier
10:  af6903a6 = 10:  af6903a6 lib/search/l/: LSEARCH(): Add macro
11:  b98586af = 11:  b98586af lib/addgrps.c: add_groups(): Simplify redundant code with a goto
12:  53a15822 = 12:  53a15822 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
13:  86cf3448 = 13:  86cf3448 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  f5543414 = 14:  f5543414 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
15:  c0f2d3aa = 15:  c0f2d3aa lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
16:  8dd9817c = 16:  8dd9817c lib/string/strchr/: strchrscnt(): Add function
17:  41ee16cc = 17:  41ee16cc lib/addgrps.c: add_groups(): Reallocate at once
 -:  -------- > 18:  74b33f54 search/cmp/: CMP(), cmp_int(), cmp_int(), cmp_uint(), cmp_ulong(): Add macro and functions
 -:  -------- > 19:  bfc821d4 lib/: LSEARCH(), LFIND(): Use CMP() to automatically detect the right comparison function
 -:  -------- > 20:  cef0e6d7 lib/search/cmp/: cmp_gid(): Remove unused function
v5b
  • Remove old include
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  a78be8a3 =  4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
 5:  35341fd7 =  5:  35341fd7 lib/: cmp_long(): Move and rename function
 6:  50c01c13 =  6:  50c01c13 lib/search/l/: LFIND(): Add macro
 7:  f472749b =  7:  f472749b lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  3f5a9620 =  8:  3f5a9620 lib/addgrps.c: add_groups(): Remove useless cast
 9:  d13b47db =  9:  d13b47db lib/addgrps.c: add_groups(): Allocate earlier
10:  af6903a6 = 10:  af6903a6 lib/search/l/: LSEARCH(): Add macro
11:  b98586af = 11:  b98586af lib/addgrps.c: add_groups(): Simplify redundant code with a goto
12:  53a15822 = 12:  53a15822 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
13:  86cf3448 = 13:  86cf3448 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  f5543414 = 14:  f5543414 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
15:  c0f2d3aa = 15:  c0f2d3aa lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
16:  8dd9817c = 16:  8dd9817c lib/string/strchr/: strchrscnt(): Add function
17:  41ee16cc = 17:  41ee16cc lib/addgrps.c: add_groups(): Reallocate at once
18:  74b33f54 = 18:  74b33f54 search/cmp/: CMP(), cmp_int(), cmp_int(), cmp_uint(), cmp_ulong(): Add macro and functions
19:  bfc821d4 ! 19:  8c711ab0 lib/: LSEARCH(), LFIND(): Use CMP() to automatically detect the right comparison function
    @@ Commit message
         Signed-off-by: Alejandro Colomar <[email protected]>
     
      ## lib/addgrps.c ##
    +@@
    + 
    + #include "alloc/malloc.h"
    + #include "alloc/reallocf.h"
    +-#include "search/cmp/cmp_gid.h"
    + #include "search/l/lsearch.h"
    + #include "shadowlog.h"
    + #include "string/strchr/strchrscnt.h"
     @@ lib/addgrps.c: add_groups(const char *list)
                        continue;
                }
20:  cef0e6d7 = 20:  bf9f0b36 lib/search/cmp/: cmp_gid(): Remove unused function
v5c
  • Fix macro (I forgot to add a *).
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  a78be8a3 =  4:  a78be8a3 lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
 5:  35341fd7 =  5:  35341fd7 lib/: cmp_long(): Move and rename function
 6:  50c01c13 =  6:  50c01c13 lib/search/l/: LFIND(): Add macro
 7:  f472749b =  7:  f472749b lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  3f5a9620 =  8:  3f5a9620 lib/addgrps.c: add_groups(): Remove useless cast
 9:  d13b47db =  9:  d13b47db lib/addgrps.c: add_groups(): Allocate earlier
10:  af6903a6 = 10:  af6903a6 lib/search/l/: LSEARCH(): Add macro
11:  b98586af = 11:  b98586af lib/addgrps.c: add_groups(): Simplify redundant code with a goto
12:  53a15822 = 12:  53a15822 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
13:  86cf3448 = 13:  86cf3448 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  f5543414 = 14:  f5543414 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
15:  c0f2d3aa = 15:  c0f2d3aa lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
16:  8dd9817c = 16:  8dd9817c lib/string/strchr/: strchrscnt(): Add function
17:  41ee16cc = 17:  41ee16cc lib/addgrps.c: add_groups(): Reallocate at once
18:  74b33f54 ! 18:  9920ee43 search/cmp/: CMP(), cmp_int(), cmp_int(), cmp_uint(), cmp_ulong(): Add macro and functions
    @@ lib/search/cmp/cmp.h (new)
     +#define CMP(TYPE)                                                     \
     +(                                                                     \
     +  _Generic((TYPE) 0,                                            \
    -+          int:            cmp_int,                              \
    -+          long:           cmp_long,                             \
    -+          unsigned int:   cmp_uint,                             \
    -+          unsigned long:  cmp_ulong                             \
    ++          int *:            cmp_int,                            \
    ++          long *:           cmp_long,                           \
    ++          unsigned int *:   cmp_uint,                           \
    ++          unsigned long *:  cmp_ulong                           \
     +  )                                                             \
     +)
     +
19:  8c711ab0 = 19:  63d42e5a lib/: LSEARCH(), LFIND(): Use CMP() to automatically detect the right comparison function
20:  bf9f0b36 = 20:  d0f9231b lib/search/cmp/: cmp_gid(): Remove unused function
v6
  • Merge several commits
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  a78be8a3 <  -:  -------- lib/search/cmp/: cmp_gid(): Add function for use with bsearch(3),lfind(3),qsort(3)
 5:  35341fd7 !  4:  e5ec508a lib/: cmp_long(): Move and rename function
    @@ Metadata
     Author: Alejandro Colomar <[email protected]>
     
      ## Commit message ##
    -    lib/: cmp_long(): Move and rename function
    +    lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
     
    -    For consistency with cmp_gid().
    +    These macros are for use with bsearch(3),lfind(3),qsort(3).
     
         Signed-off-by: Alejandro Colomar <[email protected]>
     
      ## lib/Makefile.am ##
     @@ lib/Makefile.am: libshadow_la_SOURCES = \
    +   run_part.h \
    +   run_part.c \
        salt.c \
    -   search/cmp/cmp_gid.c \
    -   search/cmp/cmp_gid.h \
    -+  search/cmp/cmp_long.c \
    -+  search/cmp/cmp_long.h \
    ++  search/cmp/cmp.c \
    ++  search/cmp/cmp.h \
        selinux.c \
        semanage.c \
        setugid.c \
    @@ lib/adds.h
      #include <stddef.h>
      #include <stdlib.h>
      
    -+#include "search/cmp/cmp_long.h"
    ++#include "search/cmp/cmp.h"
      #include "sizeof.h"
      
      
    @@ lib/adds.h: addslN(size_t n, long addend[n])
     -
      #endif  // include guard
     
    - ## lib/search/cmp/cmp_long.c (new) ##
    + ## lib/search/cmp/cmp.c (new) ##
     @@
    -+// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <[email protected]>
    ++// SPDX-FileCopyrightText: 2024, Alejandro Colomar <[email protected]>
     +// SPDX-License-Identifier: BSD-3-Clause
     +
     +
     +#include <config.h>
     +
    -+#include "search/cmp/cmp_long.h"
    ++#include "search/cmp/cmp.h"
     +
     +
    ++extern inline int cmp_int(const void *key, const void *elt);
     +extern inline int cmp_long(const void *key, const void *elt);
    ++extern inline int cmp_uint(const void *key, const void *elt);
    ++extern inline int cmp_ulong(const void *key, const void *elt);
     
    - ## lib/search/cmp/cmp_long.h (new) ##
    + ## lib/search/cmp/cmp.h (new) ##
     @@
    -+// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <[email protected]>
    ++// SPDX-FileCopyrightText: 2024, Alejandro Colomar <[email protected]>
     +// SPDX-License-Identifier: BSD-3-Clause
     +
     +
    -+#ifndef SHADOW_INCLUDE_LIB_SEARCH_CMP_CMP_LONG_H_
    -+#define SHADOW_INCLUDE_LIB_SEARCH_CMP_CMP_LONG_H_
    ++#ifndef SHADOW_INCLUDE_LIB_SEARCH_CMP_CMP_H_
    ++#define SHADOW_INCLUDE_LIB_SEARCH_CMP_CMP_H_
     +
     +
     +#include <config.h>
     +
     +
    -+inline int cmp_long(const void *key, const void *elt);
    ++#define CMP(TYPE)                                                     \
    ++(                                                                     \
    ++  _Generic((TYPE) 0,                                            \
    ++          int *:            cmp_int,                            \
    ++          long *:           cmp_long,                           \
    ++          unsigned int *:   cmp_uint,                           \
    ++          unsigned long *:  cmp_ulong                           \
    ++  )                                                             \
    ++)
     +
     +
     +/* Compatible with bsearch(3), lfind(3), and qsort(3).  */
    ++inline int cmp_int(const void *key, const void *elt);
    ++inline int cmp_long(const void *key, const void *elt);
    ++inline int cmp_uint(const void *key, const void *elt);
    ++inline int cmp_ulong(const void *key, const void *elt);
    ++
    ++
    ++inline int
    ++cmp_int(const void *key, const void *elt)
    ++{
    ++  const int  *k = key;
    ++  const int  *e = elt;
    ++
    ++  if (*k < *e)
    ++          return -1;
    ++  if (*k > *e)
    ++          return +1;
    ++  return 0;
    ++}
    ++
    ++
     +inline int
     +cmp_long(const void *key, const void *elt)
     +{
    @@ lib/search/cmp/cmp_long.h (new)
     +}
     +
     +
    ++inline int
    ++cmp_uint(const void *key, const void *elt)
    ++{
    ++  const unsigned int  *k = key;
    ++  const unsigned int  *e = elt;
    ++
    ++  if (*k < *e)
    ++          return -1;
    ++  if (*k > *e)
    ++          return +1;
    ++  return 0;
    ++}
    ++
    ++
    ++inline int
    ++cmp_ulong(const void *key, const void *elt)
    ++{
    ++  const unsigned long  *k = key;
    ++  const unsigned long  *e = elt;
    ++
    ++  if (*k < *e)
    ++          return -1;
    ++  if (*k > *e)
    ++          return +1;
    ++  return 0;
    ++}
    ++
    ++
     +#endif  // include guard
     
      ## tests/unit/Makefile.am ##
    @@ tests/unit/Makefile.am: check_PROGRAMS += \
      
      test_adds_SOURCES = \
          ../../lib/adds.c \
    -+    ../../lib/search/cmp/cmp_long.c \
    ++    ../../lib/search/cmp/cmp.c \
          test_adds.c \
          $(NULL)
      test_adds_CFLAGS = \
 6:  50c01c13 !  5:  d036c54b lib/search/l/: LFIND(): Add macro
    @@ Commit message
     
      ## lib/Makefile.am ##
     @@ lib/Makefile.am: libshadow_la_SOURCES = \
    -   search/cmp/cmp_gid.h \
    -   search/cmp/cmp_long.c \
    -   search/cmp/cmp_long.h \
    +   salt.c \
    +   search/cmp/cmp.c \
    +   search/cmp/cmp.h \
     +  search/l/lfind.c \
     +  search/l/lfind.h \
        selinux.c \
    @@ lib/search/l/lfind.h (new)
     +#include <stddef.h>
     +
     +#include "must_be.h"
    ++#include "search/cmp/cmp.h"
     +
     +#include <assert.h>
     +
     +
    -+#define LFIND(k, a, n, cmp)                                           \
    ++#define LFIND(k, a, n)                                                \
     +({                                                                    \
     +  __auto_type  k_ = k;                                          \
     +  __auto_type  a_ = a;                                          \
     +                                                                      \
     +  static_assert(is_same_typeof(k_, a_), "");                    \
     +                                                                      \
    -+  (typeof(k_)) lfind_(k_, a_, n, sizeof(*k_), cmp);             \
    ++  (typeof(k_)) lfind_(k_, a_, n, sizeof(*k_), CMP(typeof(k_))); \
     +})
     +
     +
 7:  f472749b !  6:  0a66395e lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
    @@ lib/addgrps.c
      
      #include "alloc/malloc.h"
      #include "alloc/reallocf.h"
    -+#include "search/cmp/cmp_gid.h"
     +#include "search/l/lfind.h"
      #include "shadowlog.h"
      
    @@ lib/addgrps.c: add_groups(const char *list)
     -          for (i = 0; i < (size_t)ngroups && grouplist[i] != grp->gr_gid; i++);
     -
     -          if (i < (size_t)ngroups) {
    -+          if (LFIND(&grp->gr_gid, grouplist, ngroups, cmp_gid) != NULL)
    ++          if (LFIND(&grp->gr_gid, grouplist, ngroups) != NULL)
                        continue;
     -          }
      
 8:  3f5a9620 =  7:  70d26442 lib/addgrps.c: add_groups(): Remove useless cast
 9:  d13b47db !  8:  94b95bea lib/addgrps.c: add_groups(): Allocate earlier
    @@ lib/addgrps.c: add_groups(const char *list)
     +          if (grouplist == NULL)
     +                  return -1;
     +
    -           if (LFIND(&grp->gr_gid, grouplist, ngroups, cmp_gid) != NULL)
    +           if (LFIND(&grp->gr_gid, grouplist, ngroups) != NULL)
                        continue;
      
     @@ lib/addgrps.c: add_groups(const char *list)
10:  af6903a6 !  9:  af58833c lib/search/l/: LSEARCH(): Add macro
    @@ Commit message
     
      ## lib/Makefile.am ##
     @@ lib/Makefile.am: libshadow_la_SOURCES = \
    -   search/cmp/cmp_long.h \
    +   search/cmp/cmp.h \
        search/l/lfind.c \
        search/l/lfind.h \
     +  search/l/lsearch.c \
    @@ lib/search/l/lsearch.h (new)
     +#include <search.h>
     +
     +#include "must_be.h"
    ++#include "search/cmp/cmp.h"
     +
     +#include <assert.h>
     +
     +
    -+#define LSEARCH(k, a, n, cmp)                                         \
    ++#define LSEARCH(k, a, n)                                              \
     +({                                                                    \
     +  __auto_type  k_ = k;                                          \
     +  __auto_type  a_ = a;                                          \
     +                                                                      \
     +  static_assert(is_same_typeof(k_, a_), "");                    \
     +                                                                      \
    -+  (typeof(k_)) lsearch(k_, a_, n, sizeof(*k_), cmp);            \
    ++  (typeof(k_)) lsearch(k_, a_, n, sizeof(*k_), CMP(typeof(k_)));\
     +})
     +
     +
11:  b98586af = 10:  cedfaae0 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
12:  53a15822 = 11:  253e7ef4 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
13:  86cf3448 ! 12:  6cdbb433 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
    @@ Commit message
     
      ## lib/addgrps.c ##
     @@
    + 
      #include "alloc/malloc.h"
      #include "alloc/reallocf.h"
    - #include "search/cmp/cmp_gid.h"
     -#include "search/l/lfind.h"
     +#include "search/l/lsearch.h"
      #include "shadowlog.h"
    @@ lib/addgrps.c: add_groups(const char *list)
                if (grouplist == NULL)
                        return -1;
      
    --          if (LFIND(&grp->gr_gid, grouplist, ngroups, cmp_gid) != NULL)
    +-          if (LFIND(&grp->gr_gid, grouplist, ngroups) != NULL)
     -                  continue;
    -+          LSEARCH(&grp->gr_gid, grouplist, &ngroups, cmp_gid);
    ++          LSEARCH(&grp->gr_gid, grouplist, &ngroups);
      
                if (ngroups >= sysconf (_SC_NGROUPS_MAX)) {
                        fputs (_("Warning: too many groups\n"), shadow_logfd);
14:  f5543414 ! 13:  f585cb28 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
    @@ lib/addgrps.c
     @@ lib/addgrps.c: add_groups(const char *list)
                        return -1;
      
    -           LSEARCH(&grp->gr_gid, grouplist, &ngroups, cmp_gid);
    +           LSEARCH(&grp->gr_gid, grouplist, &ngroups);
     -
     -          if (ngroups >= sysconf (_SC_NGROUPS_MAX)) {
     -                  fputs (_("Warning: too many groups\n"), shadow_logfd);
15:  c0f2d3aa ! 14:  e28f1a3d lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
    @@ lib/addgrps.c: add_groups(const char *list)
                if (grouplist == NULL)
                        return -1;
      
    --          LSEARCH(&grp->gr_gid, grouplist, &ngroups, cmp_gid);
    -+          LSEARCH(&grp->gr_gid, grouplist, &n, cmp_gid);
    +-          LSEARCH(&grp->gr_gid, grouplist, &ngroups);
    ++          LSEARCH(&grp->gr_gid, grouplist, &n);
        }
      
     -  if (setgroups(ngroups, grouplist) == -1) {
16:  8dd9817c = 15:  102108b0 lib/string/strchr/: strchrscnt(): Add function
17:  41ee16cc ! 16:  ecb74d52 lib/addgrps.c: add_groups(): Reallocate at once
    @@ Commit message
     
      ## lib/addgrps.c ##
     @@
    - #include "search/cmp/cmp_gid.h"
    + #include "alloc/reallocf.h"
      #include "search/l/lsearch.h"
      #include "shadowlog.h"
     -
    @@ lib/addgrps.c: add_groups(const char *list)
     -          if (grouplist == NULL)
     -                  return -1;
     -
    -           LSEARCH(&grp->gr_gid, grouplist, &n, cmp_gid);
    +           LSEARCH(&grp->gr_gid, grouplist, &n);
        }
      
18:  9920ee43 <  -:  -------- search/cmp/: CMP(), cmp_int(), cmp_int(), cmp_uint(), cmp_ulong(): Add macro and functions
19:  63d42e5a <  -:  -------- lib/: LSEARCH(), LFIND(): Use CMP() to automatically detect the right comparison function
20:  d0f9231b <  -:  -------- lib/search/cmp/: cmp_gid(): Remove unused function
v7
  • Add QSORT().
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  e5ec508a =  4:  e5ec508a lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  d036c54b =  5:  d036c54b lib/search/l/: LFIND(): Add macro
 6:  0a66395e =  6:  0a66395e lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 7:  70d26442 =  7:  70d26442 lib/addgrps.c: add_groups(): Remove useless cast
 8:  94b95bea =  8:  94b95bea lib/addgrps.c: add_groups(): Allocate earlier
 9:  af58833c =  9:  af58833c lib/search/l/: LSEARCH(): Add macro
10:  cedfaae0 = 10:  cedfaae0 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
11:  253e7ef4 = 11:  253e7ef4 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
12:  6cdbb433 = 12:  6cdbb433 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
13:  f585cb28 = 13:  f585cb28 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
14:  e28f1a3d = 14:  e28f1a3d lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  102108b0 = 15:  102108b0 lib/string/strchr/: strchrscnt(): Add function
16:  ecb74d52 = 16:  ecb74d52 lib/addgrps.c: add_groups(): Reallocate at once
 -:  -------- > 17:  2536e4a4 lib/search/sort/: QSORT(): Add macro
 -:  -------- > 18:  5fd21a96 lib/adds.h: addslN(): Use QSORT() instead of its pattern
v7b
  • Remove unused include
$ git range-diff shadow/master gh/add_groups add_groups 
 1:  40a468ab =  1:  40a468ab lib/, src/: Use strsep(3) instead of strtok(3)
 2:  9615bacf =  2:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 3:  e6069988 =  3:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 4:  c592e66a =  4:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 5:  e5ec508a =  5:  e5ec508a lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 6:  d036c54b =  6:  d036c54b lib/search/l/: LFIND(): Add macro
 7:  0a66395e =  7:  0a66395e lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  70d26442 =  8:  70d26442 lib/addgrps.c: add_groups(): Remove useless cast
 9:  94b95bea =  9:  94b95bea lib/addgrps.c: add_groups(): Allocate earlier
10:  af58833c = 10:  af58833c lib/search/l/: LSEARCH(): Add macro
11:  cedfaae0 = 11:  cedfaae0 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
12:  253e7ef4 = 12:  253e7ef4 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
13:  6cdbb433 = 13:  6cdbb433 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  f585cb28 = 14:  f585cb28 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
15:  e28f1a3d = 15:  e28f1a3d lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
16:  102108b0 = 16:  102108b0 lib/string/strchr/: strchrscnt(): Add function
17:  ecb74d52 = 17:  ecb74d52 lib/addgrps.c: add_groups(): Reallocate at once
18:  2536e4a4 = 18:  2536e4a4 lib/search/sort/: QSORT(): Add macro
19:  5fd21a96 ! 19:  080b7c72 lib/adds.h: addslN(): Use QSORT() instead of its pattern
    @@ lib/adds.h
      #include <stddef.h>
     -#include <stdlib.h>
      
    - #include "search/cmp/cmp.h"
    +-#include "search/cmp/cmp.h"
     +#include "search/sort/qsort.h"
      #include "sizeof.h"
      
v8
  • Use const pointer more.
  • Remove arbitrary limit.
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  e5ec508a =  4:  e5ec508a lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  d036c54b =  5:  d036c54b lib/search/l/: LFIND(): Add macro
 6:  0a66395e =  6:  0a66395e lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 7:  70d26442 =  7:  70d26442 lib/addgrps.c: add_groups(): Remove useless cast
 8:  94b95bea =  8:  94b95bea lib/addgrps.c: add_groups(): Allocate earlier
 9:  af58833c =  9:  af58833c lib/search/l/: LSEARCH(): Add macro
10:  cedfaae0 = 10:  cedfaae0 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
11:  253e7ef4 = 11:  253e7ef4 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
12:  6cdbb433 = 12:  6cdbb433 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
13:  f585cb28 = 13:  f585cb28 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
14:  e28f1a3d = 14:  e28f1a3d lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  102108b0 = 15:  102108b0 lib/string/strchr/: strchrscnt(): Add function
16:  ecb74d52 ! 16:  233f787a lib/addgrps.c: add_groups(): Reallocate at once
    @@ lib/addgrps.c: add_groups(const char *list)
        if (n0 == -1)
                goto fail;
      
    -+  grouplist = REALLOCF(grouplist, n0 + strchrscnt(buf, ",:") + 1, GETGROUPS_T);
    ++  grouplist = REALLOCF(grouplist, n0 + strchrscnt(list, ",:") + 1, GETGROUPS_T);
     +  if (grouplist == NULL)
     +          return -1;
     +
17:  2536e4a4 = 17:  50d9637f lib/search/sort/: QSORT(): Add macro
18:  080b7c72 = 18:  6df27d5a lib/adds.h: addslN(): Use QSORT() instead of its pattern
 -:  -------- > 19:  733768aa lib/addgrps.c: add_groups(): Remove arbitrary limit
v9
  • Rename variable (and goto label)
  • Reorder commits
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  e5ec508a =  4:  e5ec508a lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  d036c54b =  5:  d036c54b lib/search/l/: LFIND(): Add macro
 6:  0a66395e =  6:  0a66395e lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 7:  70d26442 =  7:  70d26442 lib/addgrps.c: add_groups(): Remove useless cast
 8:  94b95bea =  8:  94b95bea lib/addgrps.c: add_groups(): Allocate earlier
 9:  af58833c =  9:  af58833c lib/search/l/: LSEARCH(): Add macro
10:  cedfaae0 = 10:  cedfaae0 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
11:  253e7ef4 = 11:  253e7ef4 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
12:  6cdbb433 = 12:  6cdbb433 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
13:  f585cb28 = 13:  f585cb28 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
14:  e28f1a3d = 14:  e28f1a3d lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  102108b0 = 15:  102108b0 lib/string/strchr/: strchrscnt(): Add function
16:  233f787a = 16:  233f787a lib/addgrps.c: add_groups(): Reallocate at once
19:  733768aa ! 17:  48bc8216 lib/addgrps.c: add_groups(): Remove arbitrary limit
    @@ lib/addgrps.c: int
        n0 = getgroups(n0, grouplist);
        if (n0 == -1)
     -          goto fail;
    -+          goto free_gl;
    ++          goto free_groups;
      
        grouplist = REALLOCF(grouplist, n0 + strchrscnt(list, ",:") + 1, GETGROUPS_T);
        if (grouplist == NULL)
    @@ lib/addgrps.c: add_groups(const char *list)
        if (setgroups(n, grouplist) == -1) {
                fprintf(shadow_logfd, "setgroups: %s\n", strerror(errno));
     -          goto fail;
    -+          goto free_gl;
    ++          goto free_groups;
        }
      
        free(grouplist);
    @@ lib/addgrps.c: add_groups(const char *list)
        return 0;
     -fail:
     +
    -+free_gl:
    ++free_groups:
        free(grouplist);
     +free_dup:
     +  free(dup);
 -:  -------- > 18:  fbd6aa7b lib/addgrps.c: add_groups(): Rename local variable
17:  50d9637f = 19:  e7c8794f lib/search/sort/: QSORT(): Add macro
18:  6df27d5a = 20:  b6d2af1b lib/adds.h: addslN(): Use QSORT() instead of its pattern
v9b
  • Rename local variable (and goto label).
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  e5ec508a =  4:  e5ec508a lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  d036c54b =  5:  d036c54b lib/search/l/: LFIND(): Add macro
 6:  0a66395e =  6:  0a66395e lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 7:  70d26442 =  7:  70d26442 lib/addgrps.c: add_groups(): Remove useless cast
 8:  94b95bea =  8:  94b95bea lib/addgrps.c: add_groups(): Allocate earlier
 9:  af58833c =  9:  af58833c lib/search/l/: LSEARCH(): Add macro
10:  cedfaae0 = 10:  cedfaae0 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
11:  253e7ef4 = 11:  253e7ef4 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
12:  6cdbb433 = 12:  6cdbb433 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
13:  f585cb28 = 13:  f585cb28 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
14:  e28f1a3d = 14:  e28f1a3d lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  102108b0 = 15:  102108b0 lib/string/strchr/: strchrscnt(): Add function
16:  233f787a = 16:  233f787a lib/addgrps.c: add_groups(): Reallocate at once
17:  48bc8216 = 17:  48bc8216 lib/addgrps.c: add_groups(): Remove arbitrary limit
18:  fbd6aa7b ! 18:  98d4ecd8 lib/addgrps.c: add_groups(): Rename local variable
    @@ Commit message
         Since 'list' is used in this function for a comma/colon-separated-value
         list, grouplist is incorrect and inconsistent.  grouplist is not a list,
         but an array.  Use the more common convention of just using plural.
    -    That's also more consistent with [gs]etgroups(2).
    +    Also, use 'gids' to distinguish it from other group representations.
     
         Signed-off-by: Alejandro Colomar <[email protected]>
     
    @@ lib/addgrps.c
      add_groups(const char *list)
      {
     -  GETGROUPS_T *grouplist;
    -+  GETGROUPS_T  *groups;
    ++  GETGROUPS_T  *gids;
        char     *g, *p, *dup;
        FILE *shadow_logfd = log_get_logfd();
        size_t   n;
    @@ lib/addgrps.c: add_groups(const char *list)
      
     -  grouplist = MALLOC(n0, GETGROUPS_T);
     -  if (grouplist == NULL)
    -+  groups = MALLOC(n0, GETGROUPS_T);
    -+  if (groups == NULL)
    ++  gids = MALLOC(n0, GETGROUPS_T);
    ++  if (gids == NULL)
                goto free_dup;
      
     -  n0 = getgroups(n0, grouplist);
    -+  n0 = getgroups(n0, groups);
    ++  n0 = getgroups(n0, gids);
        if (n0 == -1)
    -           goto free_groups;
    +-          goto free_groups;
    ++          goto free_gids;
      
     -  grouplist = REALLOCF(grouplist, n0 + strchrscnt(list, ",:") + 1, GETGROUPS_T);
     -  if (grouplist == NULL)
    -+  groups = REALLOCF(groups, n0 + strchrscnt(list, ",:") + 1, GETGROUPS_T);
    -+  if (groups == NULL)
    ++  gids = REALLOCF(gids, n0 + strchrscnt(list, ",:") + 1, GETGROUPS_T);
    ++  if (gids == NULL)
                goto free_dup;
      
        n = n0;
    @@ lib/addgrps.c: add_groups(const char *list)
                }
      
     -          LSEARCH(&grp->gr_gid, grouplist, &n);
    -+          LSEARCH(&grp->gr_gid, groups, &n);
    ++          LSEARCH(&grp->gr_gid, gids, &n);
        }
      
     -  if (setgroups(n, grouplist) == -1) {
    -+  if (setgroups(n, groups) == -1) {
    ++  if (setgroups(n, gids) == -1) {
                fprintf(shadow_logfd, "setgroups: %s\n", strerror(errno));
    -           goto free_groups;
    +-          goto free_groups;
    ++          goto free_gids;
        }
      
     -  free(grouplist);
    -+  free(groups);
    ++  free(gids);
        free(dup);
        return 0;
      
    - free_groups:
    +-free_groups:
     -  free(grouplist);
    -+  free(groups);
    ++free_gids:
    ++  free(gids);
      free_dup:
        free(dup);
        return -1;
19:  e7c8794f = 19:  9b6a3694 lib/search/sort/: QSORT(): Add macro
20:  b6d2af1b = 20:  2775c612 lib/adds.h: addslN(): Use QSORT() instead of its pattern
v10
  • Use gid_t instead of GETGROUPS_T.
$ git range-diff strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  c592e66a =  3:  c592e66a lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  e5ec508a =  4:  e5ec508a lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  d036c54b =  5:  d036c54b lib/search/l/: LFIND(): Add macro
 6:  0a66395e =  6:  0a66395e lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 7:  70d26442 =  7:  70d26442 lib/addgrps.c: add_groups(): Remove useless cast
 8:  94b95bea =  8:  94b95bea lib/addgrps.c: add_groups(): Allocate earlier
 9:  af58833c =  9:  af58833c lib/search/l/: LSEARCH(): Add macro
10:  cedfaae0 = 10:  cedfaae0 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
11:  253e7ef4 = 11:  253e7ef4 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
12:  6cdbb433 = 12:  6cdbb433 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
13:  f585cb28 = 13:  f585cb28 lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
14:  e28f1a3d = 14:  e28f1a3d lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  102108b0 = 15:  102108b0 lib/string/strchr/: strchrscnt(): Add function
16:  233f787a = 16:  233f787a lib/addgrps.c: add_groups(): Reallocate at once
17:  48bc8216 = 17:  48bc8216 lib/addgrps.c: add_groups(): Remove arbitrary limit
18:  98d4ecd8 = 18:  98d4ecd8 lib/addgrps.c: add_groups(): Rename local variable
19:  9b6a3694 = 19:  9b6a3694 lib/search/sort/: QSORT(): Add macro
20:  2775c612 = 20:  2775c612 lib/adds.h: addslN(): Use QSORT() instead of its pattern
 -:  -------- > 21:  9b15830b configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
v11
  • Move allocation closer to use. This results in significantly less gotos (and more returns). It also improves readability, since uses of the same variables are closer together.
  • Reorder commits. This reduces the intermediate patches.
$ git range-diff shadow/master gh/add_groups add_groups 
 1:  40a468ab =  1:  40a468ab lib/, src/: Use strsep(3) instead of strtok(3)
 2:  9615bacf =  2:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 3:  e6069988 =  3:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 4:  c592e66a !  4:  93065c9c lib/addgrps.c: add_groups(): Simplify allocation of buffer
    @@ lib/addgrps.c: add_groups(const char *list)
     +
     +  ngroups = getgroups(ngroups, grouplist);
     +  if (ngroups == -1)
    -+          goto fail;
    ++          goto free_gids;
      
        added = false;
        p = buf;
    @@ lib/addgrps.c: add_groups(const char *list)
        free (grouplist);
        return 0;
     +
    -+fail:
    ++free_gids:
     +  free(grouplist);
     +  return -1;
      }
 5:  e5ec508a =  5:  34c08d26 lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 6:  d036c54b =  6:  fbb98f1a lib/search/l/: LFIND(): Add macro
 7:  0a66395e =  7:  9ddc7f56 lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  70d26442 =  8:  4fb9302f lib/addgrps.c: add_groups(): Remove useless cast
 9:  94b95bea =  9:  2bb0bbd7 lib/addgrps.c: add_groups(): Allocate earlier
10:  af58833c = 10:  0b7c6644 lib/search/l/: LSEARCH(): Add macro
11:  cedfaae0 ! 11:  47cd7c97 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
    @@ lib/addgrps.c: add_groups(const char *list)
     +                  goto fail;
        }
      
    --  free (grouplist);
    -+  free(grouplist);
    -   return 0;
    --
    - fail:
    -   free(grouplist);
    -   return -1;
    +   free (grouplist);
12:  253e7ef4 ! 12:  675a5df8 lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
    @@ lib/addgrps.c: add_groups(const char *list)
        FILE *shadow_logfd = log_get_logfd();
     @@ lib/addgrps.c: add_groups(const char *list)
        if (ngroups == -1)
    -           goto fail;
    +           goto free_gids;
      
     -  added = false;
        p = buf;
    @@ lib/addgrps.c: add_groups(const char *list)
     +  if (setgroups(ngroups, grouplist) == -1)
     +          goto fail;
      
    -   free(grouplist);
    +   free (grouplist);
        return 0;
13:  6cdbb433 = 13:  6d1bcd0f lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  f585cb28 ! 14:  12b529bd lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
    @@ lib/addgrps.c: add_groups(const char *list)
                goto fail;
     +  }
      
    -   free(grouplist);
    +   free (grouplist);
        return 0;
15:  e28f1a3d ! 15:  ba7b060d lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
    @@ lib/addgrps.c: add_groups(const char *list)
     -  if (ngroups == -1)
     +  n0 = getgroups(n0, grouplist);
     +  if (n0 == -1)
    -           goto fail;
    +           goto free_gids;
      
     +  n = n0;
        p = buf;
16:  102108b0 = 16:  c603cdad lib/string/strchr/: strchrscnt(): Add function
17:  233f787a ! 17:  74139529 lib/addgrps.c: add_groups(): Reallocate at once
    @@ lib/addgrps.c
      /*
     @@ lib/addgrps.c: add_groups(const char *list)
        if (n0 == -1)
    -           goto fail;
    +           goto free_gids;
      
     +  grouplist = REALLOCF(grouplist, n0 + strchrscnt(list, ",:") + 1, GETGROUPS_T);
     +  if (grouplist == NULL)
18:  48bc8216 <  -:  -------- lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  98d4ecd8 ! 18:  e766e71f lib/addgrps.c: add_groups(): Rename local variable
    @@ lib/addgrps.c
      {
     -  GETGROUPS_T *grouplist;
     +  GETGROUPS_T  *gids;
    -   char     *g, *p, *dup;
    +   char *g, *p;
    +   char buf[1024];
        FILE *shadow_logfd = log_get_logfd();
    -   size_t   n;
     @@ lib/addgrps.c: add_groups(const char *list)
        if (n0 == -1)
    -           goto free_dup;
    +           return -1;
      
     -  grouplist = MALLOC(n0, GETGROUPS_T);
     -  if (grouplist == NULL)
     +  gids = MALLOC(n0, GETGROUPS_T);
     +  if (gids == NULL)
    -           goto free_dup;
    +           return -1;
      
     -  n0 = getgroups(n0, grouplist);
     +  n0 = getgroups(n0, gids);
        if (n0 == -1)
    --          goto free_groups;
    -+          goto free_gids;
    +           goto free_gids;
      
     -  grouplist = REALLOCF(grouplist, n0 + strchrscnt(list, ",:") + 1, GETGROUPS_T);
     -  if (grouplist == NULL)
     +  gids = REALLOCF(gids, n0 + strchrscnt(list, ",:") + 1, GETGROUPS_T);
     +  if (gids == NULL)
    -           goto free_dup;
    +           return -1;
      
        n = n0;
     @@ lib/addgrps.c: add_groups(const char *list)
    @@ lib/addgrps.c: add_groups(const char *list)
     -  if (setgroups(n, grouplist) == -1) {
     +  if (setgroups(n, gids) == -1) {
                fprintf(shadow_logfd, "setgroups: %s\n", strerror(errno));
    --          goto free_groups;
    -+          goto free_gids;
    +           goto fail;
        }
      
    --  free(grouplist);
    +-  free (grouplist);
     +  free(gids);
    -   free(dup);
        return 0;
      
    --free_groups:
    + free_gids:
     -  free(grouplist);
    -+free_gids:
     +  free(gids);
    - free_dup:
    -   free(dup);
        return -1;
    + }
    + #else                             /* HAVE_SETGROUPS && !USE_PAM */
 -:  -------- > 19:  190a9513 lib/addgrps.c: add_groups(): Remove arbitrary limit
20:  9b6a3694 = 20:  b2faab4f lib/search/sort/: QSORT(): Add macro
21:  2775c612 = 21:  f7c83054 lib/adds.h: addslN(): Use QSORT() instead of its pattern
22:  9b15830b ! 22:  b81d4a06 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
    @@ lib/addgrps.c
      
     @@ lib/addgrps.c: add_groups(const char *list)
        if (n0 == -1)
    -           goto free_dup;
    +           return -1;
      
     -  gids = MALLOC(n0, GETGROUPS_T);
     +  gids = MALLOC(n0, gid_t);
        if (gids == NULL)
    -           goto free_dup;
    +           return -1;
      
     @@ lib/addgrps.c: add_groups(const char *list)
        if (n0 == -1)
    @@ lib/addgrps.c: add_groups(const char *list)
     -  gids = REALLOCF(gids, n0 + strchrscnt(list, ",:") + 1, GETGROUPS_T);
     +  gids = REALLOCF(gids, n0 + strchrscnt(list, ",:") + 1, gid_t);
        if (gids == NULL)
    -           goto free_dup;
    +           return -1;
      
     
      ## src/newgrp.c ##
v12
  • free(3) earlier, to reduce gotos.
  • Fix intermediate diffs.
$ git range-diff shadow/master gh/add_groups add_groups 
 1:  40a468ab =  1:  40a468ab lib/, src/: Use strsep(3) instead of strtok(3)
 2:  9615bacf =  2:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 3:  e6069988 =  3:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 4:  93065c9c =  4:  93065c9c lib/addgrps.c: add_groups(): Simplify allocation of buffer
 5:  34c08d26 =  5:  34c08d26 lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 6:  fbb98f1a =  6:  fbb98f1a lib/search/l/: LFIND(): Add macro
 7:  9ddc7f56 =  7:  9ddc7f56 lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 8:  4fb9302f =  8:  4fb9302f lib/addgrps.c: add_groups(): Remove useless cast
 9:  2bb0bbd7 =  9:  2bb0bbd7 lib/addgrps.c: add_groups(): Allocate earlier
10:  0b7c6644 = 10:  0b7c6644 lib/search/l/: LSEARCH(): Add macro
11:  47cd7c97 ! 11:  0ce88032 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
    @@ lib/addgrps.c: add_groups(const char *list)
     -          free (grouplist);
     -          return ret;
     +          if (setgroups(ngroups, grouplist) == -1)
    -+                  goto fail;
    ++                  goto free_gids;
        }
      
        free (grouplist);
12:  675a5df8 ! 12:  2b16287c lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
    @@ lib/addgrps.c: add_groups(const char *list)
      
     -  if (added) {
     -          if (setgroups(ngroups, grouplist) == -1)
    --                  goto fail;
    +-                  goto free_gids;
     -  }
     +  if (setgroups(ngroups, grouplist) == -1)
    -+          goto fail;
    ++          goto free_gids;
      
        free (grouplist);
        return 0;
13:  6d1bcd0f = 13:  2a60066d lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
14:  12b529bd ! 14:  2b6225cf lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
    @@ lib/addgrps.c: add_groups(const char *list)
     -  if (setgroups(ngroups, grouplist) == -1)
     +  if (setgroups(ngroups, grouplist) == -1) {
     +          fprintf(shadow_logfd, "setgroups: %s\n", strerror(errno));
    -           goto fail;
    +           goto free_gids;
     +  }
      
        free (grouplist);
15:  ba7b060d ! 15:  a57fbebe lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
    @@ lib/addgrps.c: add_groups(const char *list)
     -  if (setgroups(ngroups, grouplist) == -1) {
     +  if (setgroups(n, grouplist) == -1) {
                fprintf(shadow_logfd, "setgroups: %s\n", strerror(errno));
    -           goto fail;
    +           goto free_gids;
        }
16:  c603cdad = 16:  c23d955d lib/string/strchr/: strchrscnt(): Add function
17:  74139529 = 17:  8481acaf lib/addgrps.c: add_groups(): Reallocate at once
18:  e766e71f ! 18:  6edb672e lib/addgrps.c: add_groups(): Rename local variable
    @@ lib/addgrps.c: add_groups(const char *list)
     -  if (setgroups(n, grouplist) == -1) {
     +  if (setgroups(n, gids) == -1) {
                fprintf(shadow_logfd, "setgroups: %s\n", strerror(errno));
    -           goto fail;
    +           goto free_gids;
        }
      
     -  free (grouplist);
19:  190a9513 ! 19:  d6d877e6 lib/addgrps.c: add_groups(): Remove arbitrary limit
    @@ lib/addgrps.c: add_groups(const char *list)
      
     @@ lib/addgrps.c: add_groups(const char *list)
      
    +           LSEARCH(&grp->gr_gid, gids, &n);
    +   }
    ++  free(dup);
    + 
        if (setgroups(n, gids) == -1) {
                fprintf(shadow_logfd, "setgroups: %s\n", strerror(errno));
    --          goto fail;
    -+          goto free_dup;
    -   }
    - 
    -+  free(dup);
    -   free(gids);
    -   return 0;
    - 
    -+free_dup:
    -+  free(dup);
    - free_gids:
    -   free(gids);
    -   return -1;
20:  b2faab4f = 20:  ca74b7e3 lib/search/sort/: QSORT(): Add macro
21:  f7c83054 = 21:  2b84d91b lib/adds.h: addslN(): Use QSORT() instead of its pattern
22:  b81d4a06 = 22:  f5d3c434 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
v13
  • Add agetgroups().
$ git range-diff gh/strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  93065c9c =  3:  93065c9c lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  34c08d26 =  4:  34c08d26 lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  fbb98f1a =  5:  fbb98f1a lib/search/l/: LFIND(): Add macro
 6:  9ddc7f56 =  6:  9ddc7f56 lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 7:  4fb9302f =  7:  4fb9302f lib/addgrps.c: add_groups(): Remove useless cast
 8:  2bb0bbd7 =  8:  2bb0bbd7 lib/addgrps.c: add_groups(): Allocate earlier
 9:  0b7c6644 =  9:  0b7c6644 lib/search/l/: LSEARCH(): Add macro
10:  0ce88032 = 10:  0ce88032 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
11:  2b16287c = 11:  2b16287c lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
12:  2a60066d = 12:  2a60066d lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
13:  2b6225cf = 13:  2b6225cf lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
14:  a57fbebe = 14:  a57fbebe lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  c23d955d = 15:  c23d955d lib/string/strchr/: strchrscnt(): Add function
16:  8481acaf = 16:  8481acaf lib/addgrps.c: add_groups(): Reallocate at once
17:  6edb672e = 17:  6edb672e lib/addgrps.c: add_groups(): Rename local variable
18:  d6d877e6 = 18:  d6d877e6 lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  ca74b7e3 = 19:  ca74b7e3 lib/search/sort/: QSORT(): Add macro
20:  2b84d91b = 20:  2b84d91b lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  f5d3c434 = 21:  f5d3c434 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
 -:  -------- > 22:  188a0cf2 lib/shadow/grp/: agetgroups(): Add function
 -:  -------- > 23:  c182ea5e lib/addgrps.c: add_groups(): Use agetgroups() instead of its pattern
v13b
  • Add missing include
$ git range-diff gh/strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  93065c9c =  3:  93065c9c lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  34c08d26 =  4:  34c08d26 lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  fbb98f1a =  5:  fbb98f1a lib/search/l/: LFIND(): Add macro
 6:  9ddc7f56 =  6:  9ddc7f56 lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 7:  4fb9302f =  7:  4fb9302f lib/addgrps.c: add_groups(): Remove useless cast
 8:  2bb0bbd7 =  8:  2bb0bbd7 lib/addgrps.c: add_groups(): Allocate earlier
 9:  0b7c6644 =  9:  0b7c6644 lib/search/l/: LSEARCH(): Add macro
10:  0ce88032 = 10:  0ce88032 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
11:  2b16287c = 11:  2b16287c lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
12:  2a60066d = 12:  2a60066d lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
13:  2b6225cf = 13:  2b6225cf lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
14:  a57fbebe = 14:  a57fbebe lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  c23d955d = 15:  c23d955d lib/string/strchr/: strchrscnt(): Add function
16:  8481acaf = 16:  8481acaf lib/addgrps.c: add_groups(): Reallocate at once
17:  6edb672e = 17:  6edb672e lib/addgrps.c: add_groups(): Rename local variable
18:  d6d877e6 = 18:  d6d877e6 lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  ca74b7e3 = 19:  ca74b7e3 lib/search/sort/: QSORT(): Add macro
20:  2b84d91b = 20:  2b84d91b lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  f5d3c434 = 21:  f5d3c434 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
22:  188a0cf2 = 22:  188a0cf2 lib/shadow/grp/: agetgroups(): Add function
23:  c182ea5e ! 23:  b5ab82fb lib/addgrps.c: add_groups(): Use agetgroups() instead of its pattern
    @@ lib/addgrps.c
     -#include "alloc/malloc.h"
      #include "alloc/reallocf.h"
      #include "search/l/lsearch.h"
    ++#include "shadow/grp/agetgroups.h"
      #include "shadowlog.h"
    + #include "string/strchr/strchrscnt.h"
    + 
     @@ lib/addgrps.c: add_groups(const char *list)
        FILE *shadow_logfd = log_get_logfd();
        gid_t    *gids;
v13c
  • wsfix
$ git range-diff gh/strsep gh/add_groups add_groups 
 1:  9615bacf =  1:  9615bacf lib/addgrps.c: add_groups(): Reduce scope of variables
 2:  e6069988 =  2:  e6069988 lib/addgrps.c: add_groups(): Un-spageticize code
 3:  93065c9c =  3:  93065c9c lib/addgrps.c: add_groups(): Simplify allocation of buffer
 4:  34c08d26 =  4:  34c08d26 lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  fbb98f1a =  5:  fbb98f1a lib/search/l/: LFIND(): Add macro
 6:  9ddc7f56 =  6:  9ddc7f56 lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
 7:  4fb9302f =  7:  4fb9302f lib/addgrps.c: add_groups(): Remove useless cast
 8:  2bb0bbd7 =  8:  2bb0bbd7 lib/addgrps.c: add_groups(): Allocate earlier
 9:  0b7c6644 =  9:  0b7c6644 lib/search/l/: LSEARCH(): Add macro
10:  0ce88032 = 10:  0ce88032 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
11:  2b16287c = 11:  2b16287c lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
12:  2a60066d = 12:  2a60066d lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
13:  2b6225cf = 13:  2b6225cf lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
14:  a57fbebe ! 14:  aafdcc16 lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
    @@ lib/addgrps.c: add_groups(const char *list)
        char buf[1024];
        FILE *shadow_logfd = log_get_logfd();
     -  size_t  ngroups;
    -+  size_t   n;
    -+  ssize_t  n0;
    ++  size_t  n;
    ++  ssize_t n0;
      
        if (strlen (list) >= sizeof (buf)) {
                errno = EINVAL;
15:  c23d955d = 15:  2d1c0133 lib/string/strchr/: strchrscnt(): Add function
16:  8481acaf = 16:  431ce656 lib/addgrps.c: add_groups(): Reallocate at once
17:  6edb672e = 17:  e4fb6790 lib/addgrps.c: add_groups(): Rename local variable
18:  d6d877e6 ! 18:  0ead849b lib/addgrps.c: add_groups(): Remove arbitrary limit
    @@ lib/addgrps.c: int
        GETGROUPS_T  *gids;
     -  char *g, *p;
     -  char buf[1024];
    -+  char     *g, *p, *dup;
    ++  char    *g, *p, *dup;
        FILE *shadow_logfd = log_get_logfd();
    -   size_t   n;
    -   ssize_t  n0;
    +   size_t  n;
    +   ssize_t n0;
      
     -  if (strlen (list) >= sizeof (buf)) {
     -          errno = EINVAL;
19:  ca74b7e3 = 19:  ec9f07b5 lib/search/sort/: QSORT(): Add macro
20:  2b84d91b = 20:  7636567b lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  f5d3c434 ! 21:  11bd920f configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
    @@ lib/addgrps.c
      add_groups(const char *list)
      {
     -  GETGROUPS_T  *gids;
    -   char     *g, *p, *dup;
    +   char    *g, *p, *dup;
        FILE *shadow_logfd = log_get_logfd();
    -+  gid_t    *gids;
    -   size_t   n;
    -   ssize_t  n0;
    ++  gid_t   *gids;
    +   size_t  n;
    +   ssize_t n0;
      
     @@ lib/addgrps.c: add_groups(const char *list)
        if (n0 == -1)
22:  188a0cf2 = 22:  7b9ee690 lib/shadow/grp/: agetgroups(): Add function
23:  b5ab82fb ! 23:  e661312e lib/addgrps.c: add_groups(): Use agetgroups() instead of its pattern
    @@ lib/addgrps.c
      
     @@ lib/addgrps.c: add_groups(const char *list)
        FILE *shadow_logfd = log_get_logfd();
    -   gid_t    *gids;
    -   size_t   n;
    --  ssize_t  n0;
    +   gid_t   *gids;
    +   size_t  n;
    +-  ssize_t n0;
      
     -  n0 = getgroups(0, NULL);
     -  if (n0 == -1)
v14
  • Apply the same changes to <src/newgrp.c> where it makes sense.
  • Reorder the commits so that they can also be applied to <src/newgrp.c> in a meaningful way.
  • Slightly simplify intermediate diffs.
$ git range-diff gh/strsep gh/add_groups add_groups 
 1:  9615bacf !  1:  3c2973f5 lib/addgrps.c: add_groups(): Reduce scope of variables
    @@ Metadata
     Author: Alejandro Colomar <[email protected]>
     
      ## Commit message ##
    -    lib/addgrps.c: add_groups(): Reduce scope of variables
    +    lib/, src/: Reduce scope of variables
     
         Signed-off-by: Alejandro Colomar <[email protected]>
     
    @@ lib/addgrps.c: add_groups(const char *list)
                        break;
                }
     -          /* not enough room, so try allocating a larger buffer */
    -+
                free (grouplist);
     -          i *= 2;
        }
    @@ lib/addgrps.c: add_groups(const char *list)
                ret = setgroups (ngroups, grouplist);
                free (grouplist);
                return ret;
    +
    + ## src/newgrp.c ##
    +@@ src/newgrp.c: static void syslog_sg (const char *name, const char *group)
    + int main (int argc, char **argv)
    + {
    +   bool initflag = false;
    +-  int i;
    +   bool is_member = false;
    +   bool cflag = false;
    +   int err = 0;
    +@@ src/newgrp.c: int main (int argc, char **argv)
    +    * set.
    +    */
    +   /* don't use getgroups(0, 0) - it doesn't work on some systems */
    +-  i = 16;
    +-  for (;;) {
    ++  for (int i = 16; /* void */; i *= 2) {
    +           grouplist = XMALLOC(i, GETGROUPS_T);
    +           ngroups = getgroups (i, grouplist);
    +           if (i > ngroups && !(ngroups == -1 && errno == EINVAL)) {
    +                   break;
    +           }
    +-          /* not enough room, so try allocating a larger buffer */
    +           free (grouplist);
    +-          i *= 2;
    +   }
    +   if (ngroups < 0) {
    +           perror ("getgroups");
    +@@ src/newgrp.c: int main (int argc, char **argv)
    +    * database. However getgroups() will return the group. So
    +    * if she is listed there already it is ok to grant membership.
    +    */
    +-  for (i = 0; i < ngroups; i++) {
    ++  for (int i = 0; i < ngroups; i++) {
    +           if (grp->gr_gid == grouplist[i]) {
    +                   is_member = true;
    +                   break;
    +@@ src/newgrp.c: int main (int argc, char **argv)
    +    * If the group doesn't fit, I'll complain loudly and skip this
    +    * part.
    +    */
    ++  int i;
    +   for (i = 0; i < ngroups; i++) {
    +           if (gid == grouplist[i]) {
    +                   break;
 2:  e6069988 <  -:  -------- lib/addgrps.c: add_groups(): Un-spageticize code
 -:  -------- >  2:  da607437 lib/, src/: Un-spageticize code
 3:  93065c9c !  3:  a59c718e lib/addgrps.c: add_groups(): Simplify allocation of buffer
    @@ Metadata
     Author: Alejandro Colomar <[email protected]>
     
      ## Commit message ##
    -    lib/addgrps.c: add_groups(): Simplify allocation of buffer
    +    lib/, src/: Simplify allocation of buffer
     
         getgroups(0, NULL) returns the number of groups, so that we can allocate
         at once.  This might fail if there's a race and the number of users
         grows while we're allocating, but if that happens, failing is probably a
         good thing to do.
     
    +    There was some comment saying it doesn't work on some systems, but
    +    according to gnulib, that's only NeXTstep 3.2, which we don't support.
    +
    +    Link: <https://www.gnu.org/software/gnulib/manual/html_node/getgroups.html>
         Signed-off-by: Alejandro Colomar <[email protected]>
     
      ## lib/addgrps.c ##
    @@ lib/addgrps.c: add_groups(const char *list)
     -                  free(grouplist);
     -                  return -1;
     -          }
    --          if (i > (size_t)ngroups)
    +-          if (i > (size_t)ngroups) {
     -                  break;
    +-          }
    +-          free (grouplist);
    +-  }
     +  ngroups = getgroups(0, NULL);
     +  if (ngroups == -1)
     +          return -1;
    - 
    --          free (grouplist);
    --  }
    ++
     +  grouplist = MALLOC(ngroups, GETGROUPS_T);
     +  if (grouplist == NULL)
     +          return -1;
    @@ lib/addgrps.c: add_groups(const char *list)
      }
      #else                             /* HAVE_SETGROUPS && !USE_PAM */
      extern int ISO_C_forbids_an_empty_translation_unit;
    +
    + ## src/newgrp.c ##
    +@@ src/newgrp.c: int main (int argc, char **argv)
    +    * nasty message but at least your real and effective group ids are
    +    * set.
    +    */
    +-  /* don't use getgroups(0, 0) - it doesn't work on some systems */
    +-  for (int i = 16; /* void */; i *= 2) {
    +-          grouplist = XMALLOC(i, GETGROUPS_T);
    +-          ngroups = getgroups (i, grouplist);
    +-          if (ngroups == -1 && errno != EINVAL) {
    +-                  perror("getgroups");
    ++
    ++  ngroups = getgroups(0, NULL);
    ++  if (ngroups == -1)
    ++          goto fail_gg;
    ++
    ++  grouplist = XMALLOC(ngroups, GETGROUPS_T);
    ++
    ++  ngroups = getgroups(ngroups, grouplist);
    ++  if (ngroups == -1) {
    ++fail_gg:
    ++          perror("getgroups");
    + #ifdef WITH_AUDIT
    +-                  if (group) {
    +-                          SNPRINTF(audit_buf, "changing new-group=%s", group);
    +-                          audit_logger(AUDIT_CHGRP_ID, Prog,
    +-                                       audit_buf, NULL, getuid(), 0);
    +-                  } else {
    +-                          audit_logger(AUDIT_CHGRP_ID, Prog,
    +-                                       "changing", NULL, getuid(), 0);
    +-                  }
    ++          if (group) {
    ++                  SNPRINTF(audit_buf, "changing new-group=%s", group);
    ++                  audit_logger(AUDIT_CHGRP_ID, Prog,
    ++                               audit_buf, NULL, getuid(), 0);
    ++          } else {
    ++                  audit_logger(AUDIT_CHGRP_ID, Prog,
    ++                               "changing", NULL, getuid(), 0);
    ++          }
    + #endif
    +-                  exit(EXIT_FAILURE);
    +-          }
    +-          if (i > (size_t)ngroups) {
    +-                  break;
    +-          }
    +-          free (grouplist);
    ++          exit(EXIT_FAILURE);
    +   }
    + #endif                            /* HAVE_SETGROUPS */
    + 
    +@@ src/newgrp.c: int main (int argc, char **argv)
    +    * If the group doesn't fit, I'll complain loudly and skip this
    +    * part.
    +    */
    ++  grouplist = XREALLOC(grouplist, ngroups + 1, GETGROUPS_T);
    ++
    +   int i;
    +   for (i = 0; i < ngroups; i++) {
    +           if (gid == grouplist[i]) {
 4:  34c08d26 =  4:  db9b7ac0 lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  fbb98f1a =  5:  e0fcdd57 lib/search/l/: LFIND(): Add macro
 6:  9ddc7f56 !  6:  46ade7a9 lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
    @@ Metadata
     Author: Alejandro Colomar <[email protected]>
     
      ## Commit message ##
    -    lib/addgrps.c: add_groups(): Use LFIND() instead of an open-coded search loop
    +    lib/, src/: Use LFIND() instead of open-coded search loops
     
         Signed-off-by: Alejandro Colomar <[email protected]>
     
    @@ lib/addgrps.c: add_groups(const char *list)
      
                if (ngroups >= sysconf (_SC_NGROUPS_MAX)) {
                        fputs (_("Warning: too many groups\n"), shadow_logfd);
    +
    + ## src/newgrp.c ##
    +@@
    +-/*
    +- * SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
    +- * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
    +- * SPDX-FileCopyrightText: 2001 - 2006, Tomasz Kłoczko
    +- * SPDX-FileCopyrightText: 2007 - 2008, Nicolas François
    +- *
    +- * SPDX-License-Identifier: BSD-3-Clause
    +- */
    ++// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
    ++// SPDX-FileCopyrightText: 1996-2000, Marek Michałkiewicz
    ++// SPDX-FileCopyrightText: 2001-2006, Tomasz Kłoczko
    ++// SPDX-FileCopyrightText: 2007-2008, Nicolas François
    ++// SPDX-FileCopyrightText: 2024, Alejandro Colomar <[email protected]>
    ++// SPDX-License-Identifier: BSD-3-Clause
    ++
    + 
    + #include <config.h>
    + 
    +@@
    + #include "prototypes.h"
    + /*@-exitarg@*/
    + #include "exitcodes.h"
    ++#include "search/l/lfind.h"
    + #include "shadowlog.h"
    + #include "string/sprintf/snprintf.h"
    + #include "string/strdup/xstrdup.h"
    +@@ src/newgrp.c: fail_gg:
    +    * database. However getgroups() will return the group. So
    +    * if she is listed there already it is ok to grant membership.
    +    */
    +-  for (int i = 0; i < ngroups; i++) {
    +-          if (grp->gr_gid == grouplist[i]) {
    +-                  is_member = true;
    +-                  break;
    +-          }
    +-  }
    ++  is_member = (LFIND(&grp->gr_gid, grouplist, ngroups) != NULL);
    + #endif                          /* HAVE_SETGROUPS */
    +   /*
    +    * For split groups (due to limitations of NIS), check all
    +@@ src/newgrp.c: fail_gg:
    +    */
    +   grouplist = XREALLOC(grouplist, ngroups + 1, GETGROUPS_T);
    + 
    +-  int i;
    +-  for (i = 0; i < ngroups; i++) {
    +-          if (gid == grouplist[i]) {
    +-                  break;
    +-          }
    +-  }
    +-  if (i == ngroups) {
    ++  if (LFIND(&gid, grouplist, ngroups) == NULL) {
    +           if (ngroups >= sysconf (_SC_NGROUPS_MAX)) {
    +                   (void) fputs (_("too many groups\n"), stderr);
    +           } else {
 7:  4fb9302f =  7:  f1d4f500 lib/addgrps.c: add_groups(): Remove useless cast
 8:  2bb0bbd7 =  8:  59473248 lib/addgrps.c: add_groups(): Allocate earlier
 9:  0b7c6644 =  9:  4a6ea7b5 lib/search/l/: LSEARCH(): Add macro
10:  0ce88032 = 10:  ad71a5a1 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
11:  2b16287c ! 11:  e47f99cf lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
    @@ Metadata
     Author: Alejandro Colomar <[email protected]>
     
      ## Commit message ##
    -    lib/addgrps.c: add_groups(): Unconditionally call setgroups(2)
    +    lib/, src/: Unconditionally call setgroups(2)
     
    -    It will be a no-op, and it simplifies the code, by removing the 'added'
    -    variable.
    +    Call it regardless of having added any groups.  If the group list is the
    +    same that getgroups(3) gave us, setgroups(3) will be a no-op, and it
    +    simplifies the surrounding code, by removing the 'added' variable, and
    +    allowing to call lsearch(3) instead of lfind(3).
     
         Signed-off-by: Alejandro Colomar <[email protected]>
     
    @@ lib/addgrps.c: add_groups(const char *list)
      
        free (grouplist);
        return 0;
    +
    + ## src/newgrp.c ##
    +@@ src/newgrp.c: fail_gg:
    +                   (void) fputs (_("too many groups\n"), stderr);
    +           } else {
    +                   grouplist[ngroups++] = gid;
    +-                  if (setgroups (ngroups, grouplist) != 0) {
    +-                          perror ("setgroups");
    +-                  }
    +           }
    +   }
    ++
    ++  if (setgroups(ngroups, grouplist) == -1)
    ++          perror("setgroups");
    + #endif
    + 
    +   /*
 -:  -------- > 12:  ca337b01 lib/, src/: Replace redundant checks by actual error handling
12:  2a60066d ! 13:  6df6dd70 lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
    @@ Metadata
     Author: Alejandro Colomar <[email protected]>
     
      ## Commit message ##
    -    lib/addgrps.c: add_groups(): Use LSEARCH() instead of its pattern
    +    lib/, src/: Use LSEARCH() instead of its pattern
     
         Signed-off-by: Alejandro Colomar <[email protected]>
     
    @@ lib/addgrps.c: add_groups(const char *list)
      
     -          if (LFIND(&grp->gr_gid, grouplist, ngroups) != NULL)
     -                  continue;
    -+          LSEARCH(&grp->gr_gid, grouplist, &ngroups);
    - 
    -           if (ngroups >= sysconf (_SC_NGROUPS_MAX)) {
    -                   fputs (_("Warning: too many groups\n"), shadow_logfd);
    -                   break;
    -           }
     -
     -          grouplist[ngroups] = grp->gr_gid;
     -          ngroups++;
    ++          LSEARCH(&grp->gr_gid, grouplist, &ngroups);
        }
      
    +   if (setgroups(ngroups, grouplist) == -1) {
    +
    + ## src/newgrp.c ##
    +@@
    + #include "prototypes.h"
    + /*@-exitarg@*/
    + #include "exitcodes.h"
    +-#include "search/l/lfind.h"
    ++#include "search/l/lsearch.h"
    + #include "shadowlog.h"
    + #include "string/sprintf/snprintf.h"
    + #include "string/strdup/xstrdup.h"
    +@@ src/newgrp.c: static const char *Prog;
    + extern char **newenvp;
    + 
    + #ifdef HAVE_SETGROUPS
    +-static int ngroups;
    ++static size_t  ngroups;
    + static /*@null@*/ /*@only@*/GETGROUPS_T *grouplist;
    + #endif
    + 
    +@@ src/newgrp.c: fail_gg:
    +    */
    +   grouplist = XREALLOC(grouplist, ngroups + 1, GETGROUPS_T);
    + 
    +-  if (LFIND(&gid, grouplist, ngroups) == NULL) {
    +-          grouplist[ngroups++] = gid;
    +-  }
    ++  LSEARCH(&gid, grouplist, &ngroups);
    + 
        if (setgroups(ngroups, grouplist) == -1)
    +           perror("setgroups");
13:  2b6225cf <  -:  -------- lib/addgrps.c: add_groups(): Replace redundant check by actual error handling
14:  aafdcc16 = 14:  58959f41 lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  2d1c0133 = 15:  a874eeb6 lib/string/strchr/: strchrscnt(): Add function
16:  431ce656 = 16:  8b87cd0e lib/addgrps.c: add_groups(): Reallocate at once
17:  e4fb6790 ! 17:  4f47981a lib/addgrps.c: add_groups(): Rename local variable
    @@ Metadata
     Author: Alejandro Colomar <[email protected]>
     
      ## Commit message ##
    -    lib/addgrps.c: add_groups(): Rename local variable
    +    lib/, src/: Rename variables
     
    -    Since 'list' is used in this function for a comma/colon-separated-value
    -    list, grouplist is incorrect and inconsistent.  grouplist is not a list,
    -    but an array.  Use the more common convention of just using plural.
    -    Also, use 'gids' to distinguish it from other group representations.
    +    Since 'list' is used for a comma/colon-separated-value list, grouplist
    +    is incorrect and inconsistent.  grouplist is not a list, but an array.
    +    Use the more common convention of just using plural.  Also, use 'gids'
    +    to distinguish it from other group representations.
     
         Signed-off-by: Alejandro Colomar <[email protected]>
     
    @@ lib/addgrps.c: add_groups(const char *list)
        return -1;
      }
      #else                             /* HAVE_SETGROUPS && !USE_PAM */
    +
    + ## src/newgrp.c ##
    +@@ src/newgrp.c: extern char **newenvp;
    + 
    + #ifdef HAVE_SETGROUPS
    + static size_t  ngroups;
    +-static /*@null@*/ /*@only@*/GETGROUPS_T *grouplist;
    ++static /*@null@*/ /*@only@*/GETGROUPS_T  *gids;
    + #endif
    + 
    + static bool is_newgrp;
    +@@ src/newgrp.c: int main (int argc, char **argv)
    +   if (ngroups == -1)
    +           goto fail_gg;
    + 
    +-  grouplist = XMALLOC(ngroups, GETGROUPS_T);
    ++  gids = XMALLOC(ngroups, GETGROUPS_T);
    + 
    +-  ngroups = getgroups(ngroups, grouplist);
    ++  ngroups = getgroups(ngroups, gids);
    +   if (ngroups == -1) {
    + fail_gg:
    +           perror("getgroups");
    +@@ src/newgrp.c: fail_gg:
    +    * database. However getgroups() will return the group. So
    +    * if she is listed there already it is ok to grant membership.
    +    */
    +-  is_member = (LFIND(&grp->gr_gid, grouplist, ngroups) != NULL);
    ++  is_member = (LFIND(&grp->gr_gid, gids, ngroups) != NULL);
    + #endif                          /* HAVE_SETGROUPS */
    +   /*
    +    * For split groups (due to limitations of NIS), check all
    +@@ src/newgrp.c: fail_gg:
    +    * If the group doesn't fit, I'll complain loudly and skip this
    +    * part.
    +    */
    +-  grouplist = XREALLOC(grouplist, ngroups + 1, GETGROUPS_T);
    ++  gids = XREALLOC(gids, ngroups + 1, GETGROUPS_T);
    + 
    +-  LSEARCH(&gid, grouplist, &ngroups);
    ++  LSEARCH(&gid, gids, &ngroups);
    + 
    +-  if (setgroups(ngroups, grouplist) == -1)
    ++  if (setgroups(ngroups, gids) == -1)
    +           perror("setgroups");
    + #endif
    + 
18:  0ead849b = 18:  db5e8f4d lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  ec9f07b5 = 19:  61329e7e lib/search/sort/: QSORT(): Add macro
20:  7636567b = 20:  2a8ca1bf lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  11bd920f ! 21:  4d2dc8b8 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
    @@ src/newgrp.c
     @@ src/newgrp.c: extern char **newenvp;
      
      #ifdef HAVE_SETGROUPS
    - static int ngroups;
    --static /*@null@*/ /*@only@*/GETGROUPS_T *grouplist;
    -+static /*@null@*/ /*@only@*/gid_t  *grouplist;
    + static size_t  ngroups;
    +-static /*@null@*/ /*@only@*/GETGROUPS_T  *gids;
    ++static /*@null@*/ /*@only@*/gid_t  *gids;
      #endif
      
      static bool is_newgrp;
     @@ src/newgrp.c: int main (int argc, char **argv)
    -   /* don't use getgroups(0, 0) - it doesn't work on some systems */
    -   i = 16;
    -   for (;;) {
    --          grouplist = XMALLOC(i, GETGROUPS_T);
    -+          grouplist = XMALLOC(i, gid_t);
    -           ngroups = getgroups (i, grouplist);
    -           if (i > ngroups && !(ngroups == -1 && errno == EINVAL)) {
    -                   break;
    +   if (ngroups == -1)
    +           goto fail_gg;
    + 
    +-  gids = XMALLOC(ngroups, GETGROUPS_T);
    ++  gids = XMALLOC(ngroups, gid_t);
    + 
    +   ngroups = getgroups(ngroups, gids);
    +   if (ngroups == -1) {
    +@@ src/newgrp.c: fail_gg:
    +    * If the group doesn't fit, I'll complain loudly and skip this
    +    * part.
    +    */
    +-  gids = XREALLOC(gids, ngroups + 1, GETGROUPS_T);
    ++  gids = XREALLOC(gids, ngroups + 1, gid_t);
    + 
    +   LSEARCH(&gid, gids, &ngroups);
    + 
22:  7b9ee690 = 22:  5f6ffd49 lib/shadow/grp/: agetgroups(): Add function
23:  e661312e ! 23:  7f0c9ccd lib/addgrps.c: add_groups(): Use agetgroups() instead of its pattern
    @@ Metadata
     Author: Alejandro Colomar <[email protected]>
     
      ## Commit message ##
    -    lib/addgrps.c: add_groups(): Use agetgroups() instead of its pattern
    +    lib/, src/: Use agetgroups() instead of its pattern
     
         Signed-off-by: Alejandro Colomar <[email protected]>
     
    @@ lib/addgrps.c: add_groups(const char *list)
        while (NULL != (g = strsep(&p, ",:"))) {
                struct group  *grp;
      
    +
    + ## src/newgrp.c ##
    +@@
    + #include <sys/types.h>
    + 
    + #include "agetpass.h"
    +-#include "alloc/x/xmalloc.h"
    + #include "defines.h"
    + #include "getdef.h"
    + #include "prototypes.h"
    + /*@-exitarg@*/
    + #include "exitcodes.h"
    + #include "search/l/lsearch.h"
    ++#include "shadow/grp/agetgroups.h"
    + #include "shadowlog.h"
    + #include "string/sprintf/snprintf.h"
    + #include "string/strdup/xstrdup.h"
    +@@ src/newgrp.c: int main (int argc, char **argv)
    +    * nasty message but at least your real and effective group ids are
    +    * set.
    +    */
    +-
    +-  ngroups = getgroups(0, NULL);
    +-  if (ngroups == -1)
    +-          goto fail_gg;
    +-
    +-  gids = XMALLOC(ngroups, gid_t);
    +-
    +-  ngroups = getgroups(ngroups, gids);
    +-  if (ngroups == -1) {
    +-fail_gg:
    +-          perror("getgroups");
    ++  gids = agetgroups(&ngroups);
    ++  if (gids == NULL) {
    ++          perror("agetgroups");
    + #ifdef WITH_AUDIT
    +           if (group) {
    +                   SNPRINTF(audit_buf, "changing new-group=%s", group);
v14b
  • Add missing include.
$ git range-diff gh/strsep gh/add_groups add_groups 
 1:  3c2973f5 =  1:  3c2973f5 lib/, src/: Reduce scope of variables
 2:  da607437 =  2:  da607437 lib/, src/: Un-spageticize code
 3:  a59c718e =  3:  a59c718e lib/, src/: Simplify allocation of buffer
 4:  db9b7ac0 =  4:  db9b7ac0 lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  e0fcdd57 =  5:  e0fcdd57 lib/search/l/: LFIND(): Add macro
 6:  46ade7a9 =  6:  46ade7a9 lib/, src/: Use LFIND() instead of open-coded search loops
 7:  f1d4f500 =  7:  f1d4f500 lib/addgrps.c: add_groups(): Remove useless cast
 8:  59473248 =  8:  59473248 lib/addgrps.c: add_groups(): Allocate earlier
 9:  4a6ea7b5 =  9:  4a6ea7b5 lib/search/l/: LSEARCH(): Add macro
10:  ad71a5a1 = 10:  ad71a5a1 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
11:  e47f99cf = 11:  e47f99cf lib/, src/: Unconditionally call setgroups(2)
12:  ca337b01 = 12:  ca337b01 lib/, src/: Replace redundant checks by actual error handling
13:  6df6dd70 ! 13:  e6d074b1 lib/, src/: Use LSEARCH() instead of its pattern
    @@ lib/addgrps.c: add_groups(const char *list)
     
      ## src/newgrp.c ##
     @@
    - #include "prototypes.h"
      /*@-exitarg@*/
      #include "exitcodes.h"
    --#include "search/l/lfind.h"
    + #include "search/l/lfind.h"
     +#include "search/l/lsearch.h"
      #include "shadowlog.h"
      #include "string/sprintf/snprintf.h"
14:  58959f41 = 14:  de5004af lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  a874eeb6 = 15:  22b8b24f lib/string/strchr/: strchrscnt(): Add function
16:  8b87cd0e = 16:  7605caba lib/addgrps.c: add_groups(): Reallocate at once
17:  4f47981a = 17:  3d6d268d lib/, src/: Rename variables
18:  db5e8f4d = 18:  59f21c39 lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  61329e7e = 19:  c267bfe9 lib/search/sort/: QSORT(): Add macro
20:  2a8ca1bf = 20:  9786b4ea lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  4d2dc8b8 = 21:  1a6ab778 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
22:  5f6ffd49 = 22:  94d6111f lib/shadow/grp/: agetgroups(): Add function
23:  7f0c9ccd ! 23:  c4a0fc88 lib/, src/: Use agetgroups() instead of its pattern
    @@ src/newgrp.c
      #include "defines.h"
      #include "getdef.h"
      #include "prototypes.h"
    - /*@-exitarg@*/
    +@@
      #include "exitcodes.h"
    + #include "search/l/lfind.h"
      #include "search/l/lsearch.h"
     +#include "shadow/grp/agetgroups.h"
      #include "shadowlog.h"
v14c
  • Reorder commits.
$ git range-diff gh/strsep gh/add_groups add_groups 
 1:  3c2973f5 =  1:  3c2973f5 lib/, src/: Reduce scope of variables
 2:  da607437 =  2:  da607437 lib/, src/: Un-spageticize code
 3:  a59c718e =  3:  a59c718e lib/, src/: Simplify allocation of buffer
 4:  db9b7ac0 =  4:  db9b7ac0 lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  e0fcdd57 =  5:  e0fcdd57 lib/search/l/: LFIND(): Add macro
 6:  46ade7a9 =  6:  46ade7a9 lib/, src/: Use LFIND() instead of open-coded search loops
 7:  f1d4f500 =  7:  f1d4f500 lib/addgrps.c: add_groups(): Remove useless cast
 8:  59473248 =  8:  59473248 lib/addgrps.c: add_groups(): Allocate earlier
10:  ad71a5a1 =  9:  8e917ef4 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
11:  e47f99cf = 10:  6d1d7530 lib/, src/: Unconditionally call setgroups(2)
12:  ca337b01 = 11:  69ade79c lib/, src/: Replace redundant checks by actual error handling
 9:  4a6ea7b5 = 12:  23a49dd3 lib/search/l/: LSEARCH(): Add macro
13:  e6d074b1 = 13:  ee0c5129 lib/, src/: Use LSEARCH() instead of its pattern
14:  de5004af = 14:  f4b1f10c lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  22b8b24f = 15:  c0604d2d lib/string/strchr/: strchrscnt(): Add function
16:  7605caba = 16:  9cb8f876 lib/addgrps.c: add_groups(): Reallocate at once
17:  3d6d268d = 17:  8e2733d2 lib/, src/: Rename variables
18:  59f21c39 = 18:  14a0bf42 lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  c267bfe9 = 19:  1ad6a563 lib/search/sort/: QSORT(): Add macro
20:  9786b4ea = 20:  46f5ef72 lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  1a6ab778 = 21:  c3138a00 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
22:  94d6111f = 22:  4e9211bc lib/shadow/grp/: agetgroups(): Add function
23:  c4a0fc88 = 23:  fe631616 lib/, src/: Use agetgroups() instead of its pattern
v14d
  • Use [[gnu::access()]].
$ git range-diff gh/strsep gh/add_groups add_groups 
 1:  3c2973f5 =  1:  3c2973f5 lib/, src/: Reduce scope of variables
 2:  da607437 =  2:  da607437 lib/, src/: Un-spageticize code
 3:  a59c718e =  3:  a59c718e lib/, src/: Simplify allocation of buffer
 4:  db9b7ac0 =  4:  db9b7ac0 lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  e0fcdd57 =  5:  e0fcdd57 lib/search/l/: LFIND(): Add macro
 6:  46ade7a9 =  6:  46ade7a9 lib/, src/: Use LFIND() instead of open-coded search loops
 7:  f1d4f500 =  7:  f1d4f500 lib/addgrps.c: add_groups(): Remove useless cast
 8:  59473248 =  8:  59473248 lib/addgrps.c: add_groups(): Allocate earlier
 9:  8e917ef4 =  9:  8e917ef4 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
10:  6d1d7530 = 10:  6d1d7530 lib/, src/: Unconditionally call setgroups(2)
11:  69ade79c = 11:  69ade79c lib/, src/: Replace redundant checks by actual error handling
12:  23a49dd3 = 12:  23a49dd3 lib/search/l/: LSEARCH(): Add macro
13:  ee0c5129 = 13:  ee0c5129 lib/, src/: Use LSEARCH() instead of its pattern
14:  f4b1f10c = 14:  f4b1f10c lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  c0604d2d = 15:  c0604d2d lib/string/strchr/: strchrscnt(): Add function
16:  9cb8f876 = 16:  9cb8f876 lib/addgrps.c: add_groups(): Reallocate at once
17:  8e2733d2 = 17:  8e2733d2 lib/, src/: Rename variables
18:  14a0bf42 = 18:  14a0bf42 lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  1ad6a563 = 19:  1ad6a563 lib/search/sort/: QSORT(): Add macro
20:  46f5ef72 = 20:  46f5ef72 lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  c3138a00 = 21:  c3138a00 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
22:  4e9211bc ! 22:  91ec598e lib/shadow/grp/: agetgroups(): Add function
    @@ lib/shadow/grp/agetgroups.h (new)
     +#include "attr.h"
     +
     +
    ++ATTR_ACCESS(write_only, 1)
     +ATTR_MALLOC(free)
     +inline gid_t *agetgroups(size_t *ngids);
     +
23:  fe631616 = 23:  d270a2a0 lib/, src/: Use agetgroups() instead of its pattern
v14e
  • Rebase
$ git range-diff gh/strsep..gh/add_groups strsep..add_groups 
 1:  3c2973f5 =  1:  4a62b477 lib/, src/: Reduce scope of variables
 2:  da607437 =  2:  fcda896e lib/, src/: Un-spageticize code
 3:  a59c718e =  3:  5c44c82e lib/, src/: Simplify allocation of buffer
 4:  db9b7ac0 =  4:  269242b2 lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  e0fcdd57 =  5:  06b291dc lib/search/l/: LFIND(): Add macro
 6:  46ade7a9 !  6:  0c2b9cf1 lib/, src/: Use LFIND() instead of open-coded search loops
    @@ src/newgrp.c
      #include <config.h>
      
     @@
    - #include "prototypes.h"
    - /*@-exitarg@*/
      #include "exitcodes.h"
    + #include "getdef.h"
    + #include "prototypes.h"
     +#include "search/l/lfind.h"
      #include "shadowlog.h"
      #include "string/sprintf/snprintf.h"
    - #include "string/strdup/xstrdup.h"
    + #include "string/strcmp/streq.h"
     @@ src/newgrp.c: fail_gg:
         * database. However getgroups() will return the group. So
         * if she is listed there already it is ok to grant membership.
 7:  f1d4f500 =  7:  89987df1 lib/addgrps.c: add_groups(): Remove useless cast
 8:  59473248 =  8:  96c73ba4 lib/addgrps.c: add_groups(): Allocate earlier
 9:  8e917ef4 =  9:  81c3d4c6 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
10:  6d1d7530 = 10:  54e60451 lib/, src/: Unconditionally call setgroups(2)
11:  69ade79c = 11:  b84fd321 lib/, src/: Replace redundant checks by actual error handling
12:  23a49dd3 = 12:  1b7db55e lib/search/l/: LSEARCH(): Add macro
13:  ee0c5129 ! 13:  2c363252 lib/, src/: Use LSEARCH() instead of its pattern
    @@ lib/addgrps.c: add_groups(const char *list)
     
      ## src/newgrp.c ##
     @@
    - /*@-exitarg@*/
    - #include "exitcodes.h"
    + #include "getdef.h"
    + #include "prototypes.h"
      #include "search/l/lfind.h"
     +#include "search/l/lsearch.h"
      #include "shadowlog.h"
      #include "string/sprintf/snprintf.h"
    - #include "string/strdup/xstrdup.h"
    + #include "string/strcmp/streq.h"
     @@ src/newgrp.c: static const char *Prog;
      extern char **newenvp;
      
14:  f4b1f10c = 14:  10edb1be lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  c0604d2d = 15:  370d191e lib/string/strchr/: strchrscnt(): Add function
16:  9cb8f876 = 16:  4aa2f1aa lib/addgrps.c: add_groups(): Reallocate at once
17:  8e2733d2 = 17:  18f10192 lib/, src/: Rename variables
18:  14a0bf42 = 18:  66ee804d lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  1ad6a563 = 19:  dc325456 lib/search/sort/: QSORT(): Add macro
20:  46f5ef72 = 20:  c5720228 lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  c3138a00 ! 21:  0c1d5fe0 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
    @@ src/newgrp.c
      #include "agetpass.h"
      #include "alloc/x/xmalloc.h"
     @@
    + #include "string/strcmp/streq.h"
      #include "string/strdup/xstrdup.h"
    - #include "chkname.h"
      
     +#include <assert.h>
     +
22:  91ec598e = 22:  0d042faf lib/shadow/grp/: agetgroups(): Add function
23:  d270a2a0 ! 23:  90f464b0 lib/, src/: Use agetgroups() instead of its pattern
    @@ lib/addgrps.c: add_groups(const char *list)
     
      ## src/newgrp.c ##
     @@
    - #include <sys/types.h>
    - 
    - #include "agetpass.h"
    --#include "alloc/x/xmalloc.h"
    - #include "defines.h"
    - #include "getdef.h"
      #include "prototypes.h"
    -@@
    - #include "exitcodes.h"
      #include "search/l/lfind.h"
      #include "search/l/lsearch.h"
     +#include "shadow/grp/agetgroups.h"
      #include "shadowlog.h"
      #include "string/sprintf/snprintf.h"
    - #include "string/strdup/xstrdup.h"
    + #include "string/strcmp/streq.h"
     @@ src/newgrp.c: int main (int argc, char **argv)
         * nasty message but at least your real and effective group ids are
         * set.
v14f
  • Rebase
$ git range-diff e1bad69d..gh/add_groups strsep..add_groups 
 1:  4a62b477 =  1:  1c40e630 lib/, src/: Reduce scope of variables
 2:  fcda896e =  2:  651dc2c8 lib/, src/: Un-spageticize code
 3:  5c44c82e =  3:  245ba9aa lib/, src/: Simplify allocation of buffer
 4:  269242b2 =  4:  1c71259a lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  06b291dc =  5:  f651e83f lib/search/l/: LFIND(): Add macro
 6:  0c2b9cf1 =  6:  56777706 lib/, src/: Use LFIND() instead of open-coded search loops
 7:  89987df1 =  7:  f0be8572 lib/addgrps.c: add_groups(): Remove useless cast
 8:  96c73ba4 =  8:  b97e7404 lib/addgrps.c: add_groups(): Allocate earlier
 9:  81c3d4c6 =  9:  8dbf5855 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
10:  54e60451 = 10:  8e88578d lib/, src/: Unconditionally call setgroups(2)
11:  b84fd321 = 11:  1aadc56d lib/, src/: Replace redundant checks by actual error handling
12:  1b7db55e = 12:  511ec554 lib/search/l/: LSEARCH(): Add macro
13:  2c363252 = 13:  0c41be94 lib/, src/: Use LSEARCH() instead of its pattern
14:  10edb1be = 14:  a5cc7e50 lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  370d191e = 15:  9d8ab209 lib/string/strchr/: strchrscnt(): Add function
16:  4aa2f1aa = 16:  027107f6 lib/addgrps.c: add_groups(): Reallocate at once
17:  18f10192 = 17:  3d28156c lib/, src/: Rename variables
18:  66ee804d = 18:  46c29c77 lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  dc325456 = 19:  7576915b lib/search/sort/: QSORT(): Add macro
20:  c5720228 = 20:  5cad6e43 lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  0c1d5fe0 = 21:  c3db3fd5 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
22:  0d042faf = 22:  21e066f7 lib/shadow/grp/: agetgroups(): Add function
23:  90f464b0 = 23:  b7c8de3f lib/, src/: Use agetgroups() instead of its pattern
v14g
  • Rebase
$ git range-diff 1c40e630^..gh/add_groups  strsep..add_groups 
 1:  1c40e630 =  1:  8b288f68 lib/, src/: Reduce scope of variables
 2:  651dc2c8 =  2:  d18d5b93 lib/, src/: Un-spageticize code
 3:  245ba9aa =  3:  9427105f lib/, src/: Simplify allocation of buffer
 4:  1c71259a =  4:  cb0c4ab5 lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  f651e83f =  5:  1221eba1 lib/search/l/: LFIND(): Add macro
 6:  56777706 =  6:  bbfd4cb3 lib/, src/: Use LFIND() instead of open-coded search loops
 7:  f0be8572 =  7:  6ca45774 lib/addgrps.c: add_groups(): Remove useless cast
 8:  b97e7404 =  8:  a456da01 lib/addgrps.c: add_groups(): Allocate earlier
 9:  8dbf5855 =  9:  d622cf33 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
10:  8e88578d = 10:  e545fe57 lib/, src/: Unconditionally call setgroups(2)
11:  1aadc56d = 11:  ed3f970c lib/, src/: Replace redundant checks by actual error handling
12:  511ec554 = 12:  2877e2b2 lib/search/l/: LSEARCH(): Add macro
13:  0c41be94 = 13:  86616a5d lib/, src/: Use LSEARCH() instead of its pattern
14:  a5cc7e50 = 14:  6c5b47fd lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  9d8ab209 = 15:  a211c60a lib/string/strchr/: strchrscnt(): Add function
16:  027107f6 = 16:  71b05958 lib/addgrps.c: add_groups(): Reallocate at once
17:  3d28156c = 17:  7ac3aef2 lib/, src/: Rename variables
18:  46c29c77 = 18:  642ad00d lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  7576915b = 19:  e42d95f0 lib/search/sort/: QSORT(): Add macro
20:  5cad6e43 = 20:  1ee83032 lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  c3db3fd5 = 21:  c1065cf0 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
22:  21e066f7 = 22:  457ae511 lib/shadow/grp/: agetgroups(): Add function
23:  b7c8de3f = 23:  38e0731f lib/, src/: Use agetgroups() instead of its pattern
v14h
  • Rebase
$ git range-diff strsep..gh/add_groups shadow/master..add_groups 
 1:  8b288f68 =  1:  17d10325 lib/, src/: Reduce scope of variables
 2:  d18d5b93 =  2:  0e8b5c8c lib/, src/: Un-spageticize code
 3:  9427105f =  3:  137c114f lib/, src/: Simplify allocation of buffer
 4:  cb0c4ab5 =  4:  aa207d4a lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  1221eba1 =  5:  1bb6ba47 lib/search/l/: LFIND(): Add macro
 6:  bbfd4cb3 =  6:  feda06d7 lib/, src/: Use LFIND() instead of open-coded search loops
 7:  6ca45774 =  7:  d3a21946 lib/addgrps.c: add_groups(): Remove useless cast
 8:  a456da01 =  8:  2d73108a lib/addgrps.c: add_groups(): Allocate earlier
 9:  d622cf33 =  9:  39d2f962 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
10:  e545fe57 = 10:  68b3ea80 lib/, src/: Unconditionally call setgroups(2)
11:  ed3f970c = 11:  c3005d7a lib/, src/: Replace redundant checks by actual error handling
12:  2877e2b2 = 12:  dcf64ee3 lib/search/l/: LSEARCH(): Add macro
13:  86616a5d = 13:  95bd170c lib/, src/: Use LSEARCH() instead of its pattern
14:  6c5b47fd = 14:  4066f4eb lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  a211c60a = 15:  63e8cd0d lib/string/strchr/: strchrscnt(): Add function
16:  71b05958 = 16:  14ef3af6 lib/addgrps.c: add_groups(): Reallocate at once
17:  7ac3aef2 = 17:  474d1073 lib/, src/: Rename variables
18:  642ad00d = 18:  88cba45b lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  e42d95f0 = 19:  d15e4fdc lib/search/sort/: QSORT(): Add macro
20:  1ee83032 = 20:  dae033ba lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  c1065cf0 = 21:  79ca4aaa configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
22:  457ae511 = 22:  996b9f4e lib/shadow/grp/: agetgroups(): Add function
23:  38e0731f = 23:  faafa9b8 lib/, src/: Use agetgroups() instead of its pattern
v14i
  • Rebase
$ git range-diff master..gh/add_groups shadow/master..add_groups 
 1:  17d10325 =  1:  f3b92bbb lib/, src/: Reduce scope of variables
 2:  0e8b5c8c =  2:  12f22c3f lib/, src/: Un-spageticize code
 3:  137c114f =  3:  a814666f lib/, src/: Simplify allocation of buffer
 4:  aa207d4a =  4:  ad7c601c lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  1bb6ba47 =  5:  ff1d1ebc lib/search/l/: LFIND(): Add macro
 6:  feda06d7 =  6:  b3835137 lib/, src/: Use LFIND() instead of open-coded search loops
 7:  d3a21946 =  7:  4fa676f1 lib/addgrps.c: add_groups(): Remove useless cast
 8:  2d73108a =  8:  ddc4d63b lib/addgrps.c: add_groups(): Allocate earlier
 9:  39d2f962 =  9:  cee120cb lib/addgrps.c: add_groups(): Simplify redundant code with a goto
10:  68b3ea80 = 10:  4962b6f6 lib/, src/: Unconditionally call setgroups(2)
11:  c3005d7a = 11:  38efa01f lib/, src/: Replace redundant checks by actual error handling
12:  dcf64ee3 = 12:  804554fa lib/search/l/: LSEARCH(): Add macro
13:  95bd170c = 13:  d62e0840 lib/, src/: Use LSEARCH() instead of its pattern
14:  4066f4eb = 14:  73fb0cac lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  63e8cd0d = 15:  a1624c5b lib/string/strchr/: strchrscnt(): Add function
16:  14ef3af6 = 16:  72595707 lib/addgrps.c: add_groups(): Reallocate at once
17:  474d1073 = 17:  390a30ca lib/, src/: Rename variables
18:  88cba45b = 18:  986ea300 lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  d15e4fdc = 19:  44a35fc0 lib/search/sort/: QSORT(): Add macro
20:  dae033ba = 20:  fd6096fd lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  79ca4aaa = 21:  28f68d25 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
22:  996b9f4e = 22:  520ae0d7 lib/shadow/grp/: agetgroups(): Add function
23:  faafa9b8 = 23:  6fe59eb6 lib/, src/: Use agetgroups() instead of its pattern
v14j
  • Rebase
$ git range-diff alx/master..gh/add_groups shadow/master..add_groups 
 1:  f3b92bbb =  1:  100c73b6 lib/, src/: Reduce scope of variables
 2:  12f22c3f =  2:  0bb3e9b5 lib/, src/: Un-spageticize code
 3:  a814666f =  3:  69dc50e5 lib/, src/: Simplify allocation of buffer
 4:  ad7c601c =  4:  698e979a lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  ff1d1ebc =  5:  dad97b49 lib/search/l/: LFIND(): Add macro
 6:  b3835137 =  6:  b6b7b81f lib/, src/: Use LFIND() instead of open-coded search loops
 7:  4fa676f1 =  7:  c2580744 lib/addgrps.c: add_groups(): Remove useless cast
 8:  ddc4d63b =  8:  5d3556ab lib/addgrps.c: add_groups(): Allocate earlier
 9:  cee120cb =  9:  c3e3732a lib/addgrps.c: add_groups(): Simplify redundant code with a goto
10:  4962b6f6 = 10:  1c0bd2ff lib/, src/: Unconditionally call setgroups(2)
11:  38efa01f = 11:  867959da lib/, src/: Replace redundant checks by actual error handling
12:  804554fa = 12:  920cf152 lib/search/l/: LSEARCH(): Add macro
13:  d62e0840 = 13:  8ecbca13 lib/, src/: Use LSEARCH() instead of its pattern
14:  73fb0cac = 14:  07ae7358 lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  a1624c5b = 15:  382ecf1b lib/string/strchr/: strchrscnt(): Add function
16:  72595707 = 16:  5f52f671 lib/addgrps.c: add_groups(): Reallocate at once
17:  390a30ca = 17:  89c67f8b lib/, src/: Rename variables
18:  986ea300 = 18:  3ef6292b lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  44a35fc0 = 19:  e3a80336 lib/search/sort/: QSORT(): Add macro
20:  fd6096fd = 20:  19ced74b lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  28f68d25 = 21:  e70d15d2 configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
22:  520ae0d7 = 22:  250fa567 lib/shadow/grp/: agetgroups(): Add function
23:  6fe59eb6 = 23:  152a65d9 lib/, src/: Use agetgroups() instead of its pattern
v15
  • Use typeof() for readability of function pointer types. [@Jorenar]
$ git range-diff master gh/add_groups add_groups 
 1:  100c73b6 =  1:  100c73b6 lib/, src/: Reduce scope of variables
 2:  0bb3e9b5 =  2:  0bb3e9b5 lib/, src/: Un-spageticize code
 3:  69dc50e5 =  3:  69dc50e5 lib/, src/: Simplify allocation of buffer
 4:  698e979a =  4:  698e979a lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  dad97b49 !  5:  ab9bf5e2 lib/search/l/: LFIND(): Add macro
    @@ Metadata
      ## Commit message ##
         lib/search/l/: LFIND(): Add macro
     
    +    The use of typeof() for the function pointer argument was suggested by
    +    Jorenar.  This improves readability of these complex types.
    +
         Co-authored-by: Martin Uecker <[email protected]>
    +    Cc: Jorenar <[email protected]>
         Signed-off-by: Alejandro Colomar <[email protected]>
     
      ## lib/Makefile.am ##
    @@ lib/search/l/lfind.c (new)
     +
     +
     +extern inline void *lfind_(const void *k, const void *a, size_t n, size_t ksize,
    -+    int (*cmp)(const void *k, const void *elt));
    ++    typeof(int (const void *k, const void *elt)) *cmp);
     
      ## lib/search/l/lfind.h (new) ##
     @@
    @@ lib/search/l/lfind.h (new)
     +
     +
     +inline void *lfind_(const void *k, const void *a, size_t n, size_t ksize,
    -+    int (*cmp)(const void *k, const void *elt));
    ++    typeof(int (const void *k, const void *elt)) *cmp);
     +
     +
     +inline void *
     +lfind_(const void *k, const void *a, size_t n, size_t ksize,
    -+    int (*cmp)(const void *k, const void *elt))
    ++    typeof(int (const void *k, const void *elt)) *cmp)
     +{
     +  // lfind(3) wants a pointer to n for historic reasons.
     +  return lfind(k, a, &n, ksize, cmp);
 6:  b6b7b81f =  6:  2f6af11e lib/, src/: Use LFIND() instead of open-coded search loops
 7:  c2580744 =  7:  dad697b1 lib/addgrps.c: add_groups(): Remove useless cast
 8:  5d3556ab =  8:  26129a02 lib/addgrps.c: add_groups(): Allocate earlier
 9:  c3e3732a =  9:  2b976ebe lib/addgrps.c: add_groups(): Simplify redundant code with a goto
10:  1c0bd2ff = 10:  251898dd lib/, src/: Unconditionally call setgroups(2)
11:  867959da = 11:  744e07c0 lib/, src/: Replace redundant checks by actual error handling
12:  920cf152 = 12:  16a59eb6 lib/search/l/: LSEARCH(): Add macro
13:  8ecbca13 = 13:  02e2df0c lib/, src/: Use LSEARCH() instead of its pattern
14:  07ae7358 = 14:  aba21f99 lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  382ecf1b = 15:  24060f89 lib/string/strchr/: strchrscnt(): Add function
16:  5f52f671 = 16:  f4691814 lib/addgrps.c: add_groups(): Reallocate at once
17:  89c67f8b = 17:  97b85894 lib/, src/: Rename variables
18:  3ef6292b = 18:  a3c8ce35 lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  e3a80336 = 19:  697d9d20 lib/search/sort/: QSORT(): Add macro
20:  19ced74b = 20:  41544aea lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  e70d15d2 = 21:  7376f6ba configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
22:  250fa567 = 22:  3780fd2c lib/shadow/grp/: agetgroups(): Add function
23:  152a65d9 = 23:  e02ad779 lib/, src/: Use agetgroups() instead of its pattern
v15b
  • Rebase
$ git range-diff alx/master..gh/add_groups master..add_groups 
 1:  100c73b6 =  1:  58397e3f lib/, src/: Reduce scope of variables
 2:  0bb3e9b5 =  2:  c7f88f91 lib/, src/: Un-spageticize code
 3:  69dc50e5 =  3:  0346b13e lib/, src/: Simplify allocation of buffer
 4:  698e979a =  4:  55a245c0 lib/search/cmp/, lib/, tests/: CMP(), cmp_*(): Add macro and functions
 5:  ab9bf5e2 =  5:  65ef6c4a lib/search/l/: LFIND(): Add macro
 6:  2f6af11e =  6:  785c8dbb lib/, src/: Use LFIND() instead of open-coded search loops
 7:  dad697b1 =  7:  f654c4e2 lib/addgrps.c: add_groups(): Remove useless cast
 8:  26129a02 =  8:  17a86566 lib/addgrps.c: add_groups(): Allocate earlier
 9:  2b976ebe =  9:  7cea7f76 lib/addgrps.c: add_groups(): Simplify redundant code with a goto
10:  251898dd = 10:  264e6a8f lib/, src/: Unconditionally call setgroups(2)
11:  744e07c0 = 11:  c52c5428 lib/, src/: Replace redundant checks by actual error handling
12:  16a59eb6 = 12:  c872a663 lib/search/l/: LSEARCH(): Add macro
13:  02e2df0c = 13:  4d0e4281 lib/, src/: Use LSEARCH() instead of its pattern
14:  aba21f99 = 14:  8c308008 lib/addgrps.c: add_groups(): Split variable to avoid sign-mismatch diagnostics
15:  24060f89 = 15:  6589aad5 lib/string/strchr/: strchrscnt(): Add function
16:  f4691814 = 16:  4395b22c lib/addgrps.c: add_groups(): Reallocate at once
17:  97b85894 = 17:  7bf65a10 lib/, src/: Rename variables
18:  a3c8ce35 = 18:  6ab25622 lib/addgrps.c: add_groups(): Remove arbitrary limit
19:  697d9d20 = 19:  90518e59 lib/search/sort/: QSORT(): Add macro
20:  41544aea = 20:  35eebd6b lib/adds.h: addslN(): Use QSORT() instead of its pattern
21:  7376f6ba = 21:  d32d31ab configure.ac, lib/, src/: Use gid_t instead of GETGROUPS_T
22:  3780fd2c = 22:  cdd9687e lib/shadow/grp/: agetgroups(): Add function
23:  e02ad779 = 23:  7e5c95e1 lib/, src/: Use agetgroups() instead of its pattern

@alejandro-colomar alejandro-colomar force-pushed the add_groups branch 2 times, most recently from 0506291 to 94125e4 Compare November 14, 2024 15:18
@uecker
Copy link

uecker commented Nov 14, 2024

Does it make sense as a replacement for a simple for loop? I find the utility of such macros questionable.
Looking at the surrounding code, i would also generally make indices / dims "int" for improved overflow detection.

But to the macro: It does multiple expansion of k, n, a which should be avoided. I also do not see why you need the inline function. You could create a compound literal locally &(size_t){ (n) } if you need a pointer here. (BTW: the manpage for lfind should use *.nmemb). Also, if you insist on a generic macro version, why not also make the return type correct?

@alejandro-colomar
Copy link
Collaborator Author

alejandro-colomar commented Nov 14, 2024

Does it make sense as a replacement for a simple for loop?

I don't like empty loops too much, and I think this improves the readability slightly. But yeah, I also had doubts.

We most likely have other places where we do linear search, so I'll probably reuse it elsewhere in the future.

I find the utility of such macros questionable.

I think it's more questionable if to call lfind(3) in the first place. Once we agree to call lfind(3), this wrapper is probably better, even if just for lfind_(), which already hides the *n historical accident.

Looking at the surrounding code, i would also generally make indices / dims "int" for improved overflow detection.

Hmm, yep, since getgroups(3) returns an int, it doesn't make much sense to use size_t, which forces us to use casts often. Thanks!

But to the macro: It does multiple expansion of k, n, a which should be avoided.

Hmmm.

  • n is only used once.
  • a is used twice, but one of them is within typeof(), within a _Generic selector (which is never evaluated, right?). Nevertheless, getting an __auto_type local variable and using a static_assert(3) would help readability, so I'll do it.
  • k is used 3 times. One of them is the controlling expression, which is never evaluated. I should fix the other two, I think.

I also do not see why you need the inline function. You could create a compound literal locally &(size_t){ (n) } if you need a pointer here.

I hadn't thought of it. :)

On the other hand, having slimmer macros, and moving as much as possible to a function, is a good thing to do.

(BTW: the manpage for lfind should use *.nmemb).

I don't understand this. Would you mind suggesting a patch? (Or at least some clarification.)

Also, if you insist on a generic macro version, why not also make the return type correct?

Yep, thanks!

How about this?:

$ grepc LFIND .
./lib/search/lfind/lfind.h:#define LFIND(k, a, n, cmp)                                           \
({                                                                    \
	__auto_type  k_ = k;                                          \
	__auto_type  a_ = a;                                          \
	size_t       n_ = n;                                          \
	size_t       *np_;                                            \
                                                                      \
	static_assert(is_same_typeof(k_, a_), "");                    \
                                                                      \
	/* lfind(3) $3 wants a 'size_t *n' for historic reasons.  */  \
	np_ = &(size_t){n_};                                          \
                                                                      \
	(typeof(k_)) lfind(k_, a_, np_, sizeof(*k_), cmp);            \
})
$ grepc is_same_typeof .
./lib/must_be.h:#define is_same_typeof(a, b)                                                  \
(                                                                             \
	is_same_type(typeof(a), typeof(b))                                    \
)
$ grepc is_same_type .
./lib/must_be.h:#define is_same_type(a, b)                                                    \
(                                                                             \
	__builtin_types_compatible_p(a, b)                                    \
)

@uecker
Copy link

uecker commented Nov 14, 2024

But to the macro: It does multiple expansion of k, n, a which should be avoided.

Hmmm.

* `n` is only used once.

* `a` is used twice, but one of them is within typeof(), within a _Generic selector (which is never evaluated, right?).  Nevertheless, getting an __auto_type local variable and using a static_assert(3) would help readability, so I'll do it.

* `k` is used 3 times.  One of them is the controlling expression, which is never evaluated.  I should fix the other two, I think.

There can be evaluation in typeof / sizeof when used with variably modified types. But I was thinking mainly about macro expansion itself. Maybe this is not a problem here, but if you have several macros nested this can explode quickly.

(BTW: the manpage for lfind should use *.nmemb).

I don't understand this. Would you mind suggesting a patch? (Or at least some clarification.)

My local version has [.size * .nmemb] but this is not correct if .nmemb is a pointer, then it should be [.size * (* .nmemb)]

Also, if you insist on a generic macro version, why not also make the return type correct?

Yep, thanks!

How about this?:

$ grepc LFIND .
./lib/search/lfind/lfind.h:#define LFIND(k, a, n, cmp)                                           \
({                                                                    \
	__auto_type  k_ = k;                                          \
	__auto_type  a_ = a;                                          \
	size_t       n_ = n;                                          \
	size_t       *np_;                                            \
                                                                      \
	static_assert(is_same_typeof(k_, a_), "");                    \
                                                                      \
	/* lfind(3) wants a 'size_t *n' for historic reasons.  */     \
	np_ = &(size_t){n_};                                          \
                                                                      \
	(typeof(k_)) lfind(k_, a_, np_, sizeof(*k_), cmp);            \
})

Seems ok to me. Do we need () around the arguments? (not sure)

@alejandro-colomar
Copy link
Collaborator Author

alejandro-colomar commented Nov 14, 2024

But to the macro: It does multiple expansion of k, n, a which should be avoided.

Hmmm.

* `n` is only used once.

* `a` is used twice, but one of them is within typeof(), within a _Generic selector (which is never evaluated, right?).  Nevertheless, getting an __auto_type local variable and using a static_assert(3) would help readability, so I'll do it.

* `k` is used 3 times.  One of them is the controlling expression, which is never evaluated.  I should fix the other two, I think.

There can be evaluation in typeof / sizeof when used with variably modified types.

Does typeof(vmt) evaluate within a _Generic selector? That's one of those corner cases I don't know.

But I was thinking mainly about macro expansion itself. Maybe this is not a problem here, but if you have several macros nested this can explode quickly.

Ahhh, I see. That shouldn't be a problem here. Nevertheless, for evaluation reasons it makes sense to avoid it, by using auto.

(BTW: the manpage for lfind should use *.nmemb).

I don't understand this. Would you mind suggesting a patch? (Or at least some clarification.)

My local version has [.size * .nmemb] but this is not correct if .nmemb is a pointer, then it should be [.size * (* .nmemb)]

Ahh, you're right. I'll do [*.nmemb * .size] to avoid the parentheses. (And this also adds consistency with the order of the parameters $3 and $4.)

Also, if you insist on a generic macro version, why not also make the return type correct?

Yep, thanks!
How about this?:

$ grepc LFIND .
./lib/search/lfind/lfind.h:#define LFIND(k, a, n, cmp)                                           \
({                                                                    \
	__auto_type  k_ = k;                                          \
	__auto_type  a_ = a;                                          \
	size_t       n_ = n;                                          \
	size_t       *np_;                                            \
                                                                      \
	static_assert(is_same_typeof(k_, a_), "");                    \
                                                                      \
	/* lfind(3) wants a 'size_t *n' for historic reasons.  */     \
	np_ = &(size_t){n_};                                          \
                                                                      \
	(typeof(k_)) lfind(k_, a_, np_, sizeof(*k_), cmp);            \
})

Seems ok to me. Do we need () around the arguments? (not sure)

AFAIK, they're redundant. See https://software.codidact.com/posts/290205.

BTW, I've reverted to using the inline function lfind_(), to make the macro slimmer. I don't like macros growing too much. I prefer if they are limited to what functions can't do.

$ grepc LFIND .
./lib/search/lfind/lfind.h:#define LFIND(k, a, n, cmp)                                           \
({                                                                    \
	__auto_type  k_ = k;                                          \
	__auto_type  a_ = a;                                          \
                                                                      \
	static_assert(is_same_typeof(k_, a_), "");                    \
                                                                      \
	(typeof(k_)) lfind_(k_, a_, n, sizeof(*k_), cmp);             \
})
$ grepc -tfd lfind_ .
./lib/search/lfind/lfind.h:inline void *
lfind_(const void *k, const void *a, size_t n, size_t ksize,
    int (*cmp)(const void *k, const void *elt))
{
	// lfind(3) wants a pointer to n for historic reasons.
	return lfind(k, a, &n, ksize, cmp);
}

I'll push in a moment v2 of this PR.

@uecker
Copy link

uecker commented Nov 14, 2024

There can be evaluation in typeof / sizeof when used with variably modified types.

Does typeof(vmt) evaluate within a _Generic selector? That's one of those corner cases I don't know.

No, nothing in the _Generic selector is ever evaluated.

@alejandro-colomar
Copy link
Collaborator Author

There can be evaluation in typeof / sizeof when used with variably modified types.

Does typeof(vmt) evaluate within a _Generic selector? That's one of those corner cases I don't know.

No, nothing in the _Generic selector is ever evaluated.

Thanks! I've pushed v2.

@alejandro-colomar alejandro-colomar force-pushed the add_groups branch 12 times, most recently from d0f9231 to ecb74d5 Compare November 14, 2024 20:50
@alejandro-colomar
Copy link
Collaborator Author

alejandro-colomar commented Nov 14, 2024

@uecker

The use of lfind(3) showed that we could also refactor some more to use lsearch(3), which is more compelling as a simplification.

Also, I've come up with auto-detection of the right comparison function through a _Generic(3) selector. :-)

$ grepc LSEARCH .
./lib/search/l/lsearch.h:#define LSEARCH(k, a, n)                                              \
({                                                                    \
	__auto_type  k_ = k;                                          \
	__auto_type  a_ = a;                                          \
                                                                      \
	static_assert(is_same_typeof(k_, a_), "");                    \
                                                                      \
	(typeof(k_)) lsearch(k_, a_, n, sizeof(*k_), CMP(typeof(k_)));\
})
$ grepc CMP .
./lib/search/cmp/cmp.h:#define CMP(TYPE)                                                     \
(                                                                     \
	_Generic((TYPE) 0,                                            \
		int *:            cmp_int,                            \
		long *:           cmp_long,                           \
		unsigned int *:   cmp_uint,                           \
		unsigned long *:  cmp_ulong                           \
	)                                                             \
)

That CMP() could grow as needed. Once there's something like void-that-binds, this might get simpler (no need for CMP()), but for now, it's quite nice.

@alejandro-colomar
Copy link
Collaborator Author

Queued after the release of 4.17.0.

@alejandro-colomar alejandro-colomar marked this pull request as draft December 6, 2024 12:16
@alejandro-colomar alejandro-colomar force-pushed the add_groups branch 2 times, most recently from 152a65d to e02ad77 Compare December 14, 2024 00:17
@alejandro-colomar
Copy link
Collaborator Author

WG14 is in tha house, it seems :)

@alejandro-colomar alejandro-colomar marked this pull request as ready for review December 22, 2024 11:57
alejandro-colomar and others added 23 commits January 10, 2025 14:24
Signed-off-by: Alejandro Colomar <[email protected]>
Signed-off-by: Alejandro Colomar <[email protected]>
getgroups(0, NULL) returns the number of groups, so that we can allocate
at once.  This might fail if there's a race and the number of users
grows while we're allocating, but if that happens, failing is probably a
good thing to do.

There was some comment saying it doesn't work on some systems, but
according to gnulib, that's only NeXTstep 3.2, which we don't support.

Link: <https://www.gnu.org/software/gnulib/manual/html_node/getgroups.html>
Signed-off-by: Alejandro Colomar <[email protected]>
These macros are for use with bsearch(3),lfind(3),qsort(3).

Signed-off-by: Alejandro Colomar <[email protected]>
The use of typeof() for the function pointer argument was suggested by
Jorenar.  This improves readability of these complex types.

Co-authored-by: Martin Uecker <[email protected]>
Cc: Jorenar <[email protected]>
Signed-off-by: Alejandro Colomar <[email protected]>
This will allow using lsearch(3).

Signed-off-by: Alejandro Colomar <[email protected]>
Call it regardless of having added any groups.  If the group list is the
same that getgroups(3) gave us, setgroups(3) will be a no-op, and it
simplifies the surrounding code, by removing the 'added' variable, and
allowing to call lsearch(3) instead of lfind(3).

Signed-off-by: Alejandro Colomar <[email protected]>
setgroups(2) already performs a test to check if the number of groups is
too large.  Don't do that ourselves, and also don't do it for every
iteration.  Just let setgroups(2) do it once.

Instead of our check, let's report errors from setgroups(2).

Signed-off-by: Alejandro Colomar <[email protected]>
Signed-off-by: Alejandro Colomar <[email protected]>
We can calculate an upper bound of the number of added groups by
counting the number of delimiters in the string (plus one for the
element after the last delimiter).  This avoids reallocating +1 in a
loop.

Signed-off-by: Alejandro Colomar <[email protected]>
Since 'list' is used for a comma/colon-separated-value list, grouplist
is incorrect and inconsistent.  grouplist is not a list, but an array.
Use the more common convention of just using plural.  Also, use 'gids'
to distinguish it from other group representations.

Signed-off-by: Alejandro Colomar <[email protected]>
Signed-off-by: Alejandro Colomar <[email protected]>
Autoconf's NEWS file says

*** AC_FUNC_GETGROUPS and AC_TYPE_GETGROUPS no longer run test programs.
  These macros were testing for OS bugs that we believe are at least
  twenty years in the past.  Most operating systems are now trusted to
  provide an accurate prototype for getgroups in unistd.h, and to
  implement it as specified in POSIX.

Signed-off-by: Alejandro Colomar <[email protected]>
This encapsulates the logic for calling getgroups(3), which requires two
calls plus a malloc(3) call to do it correctly.

Signed-off-by: Alejandro Colomar <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants