[PATCH] nss: Clean up function pointer/void * unions

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Mon Nov 17 18:54:10 GMT 2025



On 17/11/25 13:18, Florian Weimer wrote:
> All our targets support casts between function pointers and void *,
> so we might as well use them.
> 
> This change was largely-autogenerated, with the following prompts.
> 
> @getXXbyYY_r.c Remove the use of the `fct` union and replace it by
> pointer casts.
> 
> Apply the same change to ether_* getnetgrent_r getnssent_r netname
> publickey .
> 
> Do not use explicit `*` in function pointer calls. Replace
> `(*((lookup_function) fct))` and similar with `((lookup_function) fct)`.

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

> 
> ---
>  nss/ether_hton.c    | 13 +++++--------
>  nss/ether_ntoh.c    | 13 +++++--------
>  nss/getXXbyYY_r.c   | 15 ++++++---------
>  nss/getnetgrent_r.c | 30 +++++++++++++-----------------
>  nss/getnssent_r.c   | 50 +++++++++++++++++---------------------------------
>  sunrpc/netname.c    | 13 +++++--------
>  sunrpc/publickey.c  | 24 ++++++++----------------
>  7 files changed, 59 insertions(+), 99 deletions(-)
> 
> diff --git a/nss/ether_hton.c b/nss/ether_hton.c
> index 588828cc1e..3c5b25c537 100644
> --- a/nss/ether_hton.c
> +++ b/nss/ether_hton.c
> @@ -30,24 +30,21 @@ int
>  ether_hostton (const char *hostname, struct ether_addr *addr)
>  {
>    nss_action_list nip;
> -  union
> -  {
> -    lookup_function f;
> -    void *ptr;
> -  } fct;
> +  void *fct;
>    int no_more;
>    enum nss_status status = NSS_STATUS_UNAVAIL;
>    struct etherent etherent;
>  
> -  no_more = __nss_ethers_lookup2 (&nip, "gethostton_r", NULL, &fct.ptr);
> +  no_more = __nss_ethers_lookup2 (&nip, "gethostton_r", NULL, &fct);
>  
>    while (no_more == 0)
>      {
>        char buffer[1024];
>  
> -      status = (*fct.f) (hostname, &etherent, buffer, sizeof buffer, &errno);
> +      status = ((lookup_function) fct) (hostname, &etherent, buffer,
> +					sizeof buffer, &errno);
>  
> -      no_more = __nss_next2 (&nip, "gethostton_r", NULL, &fct.ptr, status, 0);
> +      no_more = __nss_next2 (&nip, "gethostton_r", NULL, &fct, status, 0);
>      }
>  
>    if (status == NSS_STATUS_SUCCESS)
> diff --git a/nss/ether_ntoh.c b/nss/ether_ntoh.c
> index 2185b9e386..207a3103f0 100644
> --- a/nss/ether_ntoh.c
> +++ b/nss/ether_ntoh.c
> @@ -31,24 +31,21 @@ int
>  ether_ntohost (char *hostname, const struct ether_addr *addr)
>  {
>    nss_action_list nip;
> -  union
> -  {
> -    lookup_function f;
> -    void *ptr;
> -  } fct;
> +  void *fct;
>    int no_more;
>    enum nss_status status = NSS_STATUS_UNAVAIL;
>    struct etherent etherent;
>  
> -  no_more = __nss_ethers_lookup2 (&nip, "getntohost_r", NULL, &fct.ptr);
> +  no_more = __nss_ethers_lookup2 (&nip, "getntohost_r", NULL, &fct);
>  
>    while (no_more == 0)
>      {
>        char buffer[1024];
>  
> -      status = (*fct.f) (addr, &etherent, buffer, sizeof buffer, &errno);
> +      status = ((lookup_function) fct) (addr, &etherent, buffer,
> +					sizeof buffer, &errno);
>  
> -      no_more = __nss_next2 (&nip, "getntohost_r", NULL, &fct.ptr, status, 0);
> +      no_more = __nss_next2 (&nip, "getntohost_r", NULL, &fct, status, 0);
>      }
>  
>    if (status == NSS_STATUS_SUCCESS)
> diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
> index 2b0735fb6a..9f7188ab41 100644
> --- a/nss/getXXbyYY_r.c
> +++ b/nss/getXXbyYY_r.c
> @@ -189,11 +189,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
>    LOOKUP_TYPE mergegrp;
>    char *mergebuf = NULL;
>    char *endptr = NULL;
> -  union
> -  {
> -    lookup_function l;
> -    void *ptr;
> -  } fct;
> +  void *fct;
>    int no_more, err;
>    enum nss_status status = NSS_STATUS_UNAVAIL;
>  #ifdef USE_NSCD
> @@ -258,7 +254,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
>  #endif
>  
>    no_more = DB_LOOKUP_FCT (&nip, REENTRANT_NAME_STRING,
> -			   REENTRANT2_NAME_STRING, &fct.ptr);
> +			   REENTRANT2_NAME_STRING, &fct);
>  
>    while (no_more == 0)
>      {
> @@ -266,8 +262,9 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
>        any_service = true;
>  #endif
>  
> -      status = DL_CALL_FCT (fct.l, (ADD_VARIABLES, resbuf, buffer, buflen,
> -				    &errno H_ERRNO_VAR EXTRA_VARIABLES));
> +      status = DL_CALL_FCT (((lookup_function) fct),
> +			    (ADD_VARIABLES, resbuf, buffer, buflen,
> +			     &errno H_ERRNO_VAR EXTRA_VARIABLES));
>  
>        /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
>  	 provided buffer is too small.  In this case we should give
> @@ -337,7 +334,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
>  	}
>  
>        no_more = __nss_next2 (&nip, REENTRANT_NAME_STRING,
> -			     REENTRANT2_NAME_STRING, &fct.ptr, status, 0);
> +			     REENTRANT2_NAME_STRING, &fct, status, 0);
>      }
>    free (mergebuf);
>    mergebuf = NULL;
> diff --git a/nss/getnetgrent_r.c b/nss/getnetgrent_r.c
> index f5137ad078..df16cfe150 100644
> --- a/nss/getnetgrent_r.c
> +++ b/nss/getnetgrent_r.c
> @@ -85,11 +85,7 @@ static int
>  __internal_setnetgrent_reuse (const char *group, struct __netgrent *datap,
>  			      int *errnop)
>  {
> -  union
> -  {
> -    enum nss_status (*f) (const char *, struct __netgrent *);
> -    void *ptr;
> -  } fct;
> +  void *fct;
>    enum nss_status status = NSS_STATUS_UNAVAIL;
>    struct name_list *new_elem;
>  
> @@ -97,16 +93,18 @@ __internal_setnetgrent_reuse (const char *group, struct __netgrent *datap,
>    endnetgrent_hook (datap);
>  
>    /* Cycle through all the services and run their setnetgrent functions.  */
> -  int no_more = setup (&fct.ptr, &datap->nip);
> +  int no_more = setup (&fct, &datap->nip);
>    while (! no_more)
>      {
>        assert (datap->data == NULL);
>  
>        /* Ignore status, we force check in `__nss_next2'.  */
> -      status = DL_CALL_FCT (*fct.f, (group, datap));
> +      status = DL_CALL_FCT (((enum nss_status (*) (const char *,
> +						   struct __netgrent *)) fct),
> +			    (group, datap));
>  
>        nss_action_list old_nip = datap->nip;
> -      no_more = __nss_next2 (&datap->nip, "setnetgrent", NULL, &fct.ptr,
> +      no_more = __nss_next2 (&datap->nip, "setnetgrent", NULL, &fct,
>  			     status, 0);
>  
>        if (status == NSS_STATUS_SUCCESS && ! no_more)
> @@ -372,11 +370,7 @@ innetgr (const char *netgroup, const char *host, const char *user,
>      }
>  #endif
>  
> -  union
> -  {
> -    enum nss_status (*f) (const char *, struct __netgrent *);
> -    void *ptr;
> -  } setfct;
> +  void *setfct;
>    void (*endfct) (struct __netgrent *);
>    int (*getfct) (struct __netgrent *, char *, size_t, int *);
>    struct __netgrent entry;
> @@ -391,14 +385,16 @@ innetgr (const char *netgroup, const char *host, const char *user,
>       the work during one walk through the service list.  */
>    while (1)
>      {
> -      int no_more = setup (&setfct.ptr, &entry.nip);
> +      int no_more = setup (&setfct, &entry.nip);
>        while (! no_more)
>  	{
>  	  assert (entry.data == NULL);
>  
>  	  /* Open netgroup.  */
> -	  enum nss_status status = DL_CALL_FCT (*setfct.f,
> -						(current_group, &entry));
> +	  enum nss_status status
> +	    = DL_CALL_FCT (((enum nss_status (*) (const char *,
> +						  struct __netgrent *))
> +			    setfct), (current_group, &entry));
>  
>  	  if (status == NSS_STATUS_SUCCESS
>  	      && (getfct = __nss_lookup_function (entry.nip, "getnetgrent_r"))
> @@ -474,7 +470,7 @@ innetgr (const char *netgroup, const char *host, const char *user,
>  
>  	  /* Look for the next service.  */
>  	  no_more = __nss_next2 (&entry.nip, "setnetgrent", NULL,
> -				 &setfct.ptr, status, 0);
> +				 &setfct, status, 0);
>  	}
>  
>        if (result == 0 && entry.needed_groups != NULL)
> diff --git a/nss/getnssent_r.c b/nss/getnssent_r.c
> index 56258d5f09..10166f2420 100644
> --- a/nss/getnssent_r.c
> +++ b/nss/getnssent_r.c
> @@ -53,11 +53,7 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct,
>  	      nss_action_list *last_nip, int stayopen, int *stayopen_tmp,
>  	      int res)
>  {
> -  union
> -  {
> -    setent_function f;
> -    void *ptr;
> -  } fct;
> +  void *fct;
>    int no_more;
>  
>    struct resolv_context *res_ctx = NULL;
> @@ -73,7 +69,7 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct,
>  
>    /* Cycle through the services and run their `setXXent' functions until
>       we find an available service.  */
> -  no_more = setup (func_name, lookup_fct, &fct.ptr, nip,
> +  no_more = setup (func_name, lookup_fct, &fct, nip,
>  		   startp, 1);
>    while (! no_more)
>      {
> @@ -81,9 +77,9 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct,
>        enum nss_status status;
>  
>        if (stayopen_tmp)
> -	status = DL_CALL_FCT (fct.f, (*stayopen_tmp));
> +	status = DL_CALL_FCT (((setent_function) fct), (*stayopen_tmp));
>        else
> -	status = DL_CALL_FCT (fct.f, (0));
> +	status = DL_CALL_FCT (((setent_function) fct), (0));
>  
>  
>        /* This is a special-case.  When [SUCCESS=merge] is in play,
> @@ -95,7 +91,7 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct,
>        if (nss_next_action (*nip, status) == NSS_ACTION_MERGE)
>  	no_more = 1;
>        else
> -	no_more = __nss_next2 (nip, func_name, NULL, &fct.ptr, status, 0);
> +	no_more = __nss_next2 (nip, func_name, NULL, &fct, status, 0);
>  
>        if (is_last_nip)
>  	*last_nip = *nip;
> @@ -113,11 +109,7 @@ __nss_endent (const char *func_name, db_lookup_function lookup_fct,
>  	      nss_action_list *nip, nss_action_list *startp,
>  	      nss_action_list *last_nip, int res)
>  {
> -  union
> -  {
> -    endent_function f;
> -    void *ptr;
> -  } fct;
> +  void *fct;
>    int no_more;
>  
>    struct resolv_context *res_ctx = NULL;
> @@ -132,17 +124,17 @@ __nss_endent (const char *func_name, db_lookup_function lookup_fct,
>      }
>  
>    /* Cycle through all the services and run their endXXent functions.  */
> -  no_more = setup (func_name, lookup_fct, &fct.ptr, nip, startp, 1);
> +  no_more = setup (func_name, lookup_fct, &fct, nip, startp, 1);
>    while (! no_more)
>      {
>        /* Ignore status, we force check in __NSS_NEXT.  */
> -      DL_CALL_FCT (fct.f, ());
> +      DL_CALL_FCT (((endent_function) fct), ());
>  
>        if (*nip == *last_nip)
>  	/* We have processed all services which were used.  */
>  	break;
>  
> -      no_more = __nss_next2 (nip, func_name, NULL, &fct.ptr, 0, 1);
> +      no_more = __nss_next2 (nip, func_name, NULL, &fct, 0, 1);
>      }
>    *last_nip = *nip = NULL;
>  
> @@ -159,11 +151,7 @@ __nss_getent_r (const char *getent_func_name,
>  		void *resbuf, char *buffer, size_t buflen,
>  		void **result, int *h_errnop)
>  {
> -  union
> -  {
> -    getent_function f;
> -    void *ptr;
> -  } fct;
> +  void *fct;
>    int no_more;
>    enum nss_status status;
>  
> @@ -185,13 +173,13 @@ __nss_getent_r (const char *getent_func_name,
>    /* Run through available functions, starting with the same function last
>       run.  We will repeat each function as long as it succeeds, and then go
>       on to the next service action.  */
> -  no_more = setup (getent_func_name, lookup_fct, &fct.ptr, nip,
> +  no_more = setup (getent_func_name, lookup_fct, &fct, nip,
>  		   startp, 0);
>    while (! no_more)
>      {
>        int is_last_nip = *nip == *last_nip;
>  
> -      status = DL_CALL_FCT (fct.f,
> +      status = DL_CALL_FCT (((getent_function) fct),
>  			    (resbuf, buffer, buflen, &errno, &h_errno));
>  
>        /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
> @@ -216,7 +204,7 @@ __nss_getent_r (const char *getent_func_name,
>  	      && nss_next_action (*nip, status) == NSS_ACTION_MERGE)
>  	    no_more = 1;
>  	  else
> -	    no_more = __nss_next2 (nip, getent_func_name, NULL, &fct.ptr,
> +	    no_more = __nss_next2 (nip, getent_func_name, NULL, &fct,
>  				   status, 0);
>  
>  	  if (is_last_nip)
> @@ -225,20 +213,16 @@ __nss_getent_r (const char *getent_func_name,
>  	  if (! no_more)
>  	    {
>  	      /* Call the `setXXent' function.  This wasn't done before.  */
> -	      union
> -	      {
> -		setent_function f;
> -		void *ptr;
> -	      } sfct;
> +	      void *sfct;
>  
> -	      no_more = __nss_lookup (nip, setent_func_name, NULL, &sfct.ptr);
> +	      no_more = __nss_lookup (nip, setent_func_name, NULL, &sfct);
>  
>  	      if (! no_more)
>  	        {
>  		  if (stayopen_tmp)
> -		    status = DL_CALL_FCT (sfct.f, (*stayopen_tmp));
> +		    status = DL_CALL_FCT (((setent_function) sfct), (*stayopen_tmp));
>  		  else
> -		    status = DL_CALL_FCT (sfct.f, (0));
> +		    status = DL_CALL_FCT (((setent_function) sfct), (0));
>  		}
>  	      else
>  		status = NSS_STATUS_NOTFOUND;
> diff --git a/sunrpc/netname.c b/sunrpc/netname.c
> index d342fb8964..e2acf107a5 100644
> --- a/sunrpc/netname.c
> +++ b/sunrpc/netname.c
> @@ -157,21 +157,18 @@ netname2user (const char *netname, uid_t * uidp, gid_t * gidp,
>  	      int *gidlenp, gid_t * gidlist)
>  {
>    nss_action_list nip;
> -  union
> -  {
> -    netname2user_function f;
> -    void *ptr;
> -  } fct;
> +  void *fct;
>    enum nss_status status = NSS_STATUS_UNAVAIL;
>    int no_more;
>  
> -  no_more = __nss_publickey_lookup2 (&nip, "netname2user", NULL, &fct.ptr);
> +  no_more = __nss_publickey_lookup2 (&nip, "netname2user", NULL, &fct);
>  
>    while (!no_more)
>      {
> -      status = (*fct.f) (netname, uidp, gidp, gidlenp, gidlist);
> +      status = ((netname2user_function) fct) (netname, uidp, gidp, gidlenp,
> +					      gidlist);
>  
> -      no_more = __nss_next2 (&nip, "netname2user", NULL, &fct.ptr, status, 0);
> +      no_more = __nss_next2 (&nip, "netname2user", NULL, &fct, status, 0);
>      }
>  
>    return status == NSS_STATUS_SUCCESS;
> diff --git a/sunrpc/publickey.c b/sunrpc/publickey.c
> index 2480f8234c..812cb19ca0 100644
> --- a/sunrpc/publickey.c
> +++ b/sunrpc/publickey.c
> @@ -34,21 +34,17 @@ int
>  getpublickey (const char *name, char *key)
>  {
>    nss_action_list nip;
> -  union
> -  {
> -    public_function f;
> -    void *ptr;
> -  } fct;
> +  void *fct;
>    enum nss_status status = NSS_STATUS_UNAVAIL;
>    int no_more;
>  
> -  no_more = __nss_publickey_lookup2 (&nip, "getpublickey", NULL, &fct.ptr);
> +  no_more = __nss_publickey_lookup2 (&nip, "getpublickey", NULL, &fct);
>  
>    while (! no_more)
>      {
> -      status = (*fct.f) (name, key, &errno);
> +      status = ((public_function) fct) (name, key, &errno);
>  
> -      no_more = __nss_next2 (&nip, "getpublickey", NULL, &fct.ptr, status, 0);
> +      no_more = __nss_next2 (&nip, "getpublickey", NULL, &fct, status, 0);
>      }
>  
>    return status == NSS_STATUS_SUCCESS;
> @@ -60,21 +56,17 @@ int
>  getsecretkey (const char *name, char *key, const char *passwd)
>  {
>    nss_action_list nip;
> -  union
> -  {
> -    secret_function f;
> -    void *ptr;
> -  } fct;
> +  void *fct;
>    enum nss_status status = NSS_STATUS_UNAVAIL;
>    int no_more;
>  
> -  no_more = __nss_publickey_lookup2 (&nip, "getsecretkey", NULL, &fct.ptr);
> +  no_more = __nss_publickey_lookup2 (&nip, "getsecretkey", NULL, &fct);
>  
>    while (! no_more)
>      {
> -      status = (*fct.f) (name, key, passwd, &errno);
> +      status = ((secret_function) fct) (name, key, passwd, &errno);
>  
> -      no_more = __nss_next2 (&nip, "getsecretkey", NULL, &fct.ptr, status, 0);
> +      no_more = __nss_next2 (&nip, "getsecretkey", NULL, &fct, status, 0);
>      }
>  
>    return status == NSS_STATUS_SUCCESS;
> 



More information about the Libc-alpha mailing list