select.h: update FD macros to latest FreeBSD, fix type conversion warning

Compiling

#include <sys/select.h>
void f(int X)
{
  fd_set set;
  FD_ZERO(&set);
  FD_SET(X,&set);
  FD_CLR(X+1,&set);
  (void)FD_ISSET(X+2,&set);
}

results in plenty of gcc warnings when compiled with
-Wconversion -Wsign-conversion:

  fds.c:7:2: warning: conversion to ‘long unsigned int’ from ‘int’ may
    FD_SET(X,&set);
    ^~~~~~
  [...]

The unsigned NFDBITS macro combined with the signed 1L constant
are causing lots of implicit signed/unsigned type conversions.

Fix this by updating the FD_* macro code to the latest from FreeBSD
and adding an (int) cast to _NFDBITS.

As a side-effect, this fixes the visibility of NFDBITS and
fds_bits (only if __BSD_VISIBLE).

This also eliminates the old, outdated fd_set workaround.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2020-08-03 12:40:43 +02:00
parent 3fbfcd11fb
commit 5717262b8e
1 changed files with 37 additions and 23 deletions

View File

@ -27,33 +27,47 @@ typedef __sigset_t sigset_t;
* FD_SETSIZE may be defined by the user, but the default here * FD_SETSIZE may be defined by the user, but the default here
* should be >= NOFILE (param.h). * should be >= NOFILE (param.h).
*/ */
# ifndef FD_SETSIZE #ifndef FD_SETSIZE
# define FD_SETSIZE 64 #define FD_SETSIZE 64
# endif #endif
typedef unsigned long fd_mask; typedef unsigned long __fd_mask;
# define NFDBITS (sizeof (fd_mask) * 8) /* bits per mask */ #if __BSD_VISIBLE
# ifndef _howmany typedef __fd_mask fd_mask;
# define _howmany(x,y) (((x)+((y)-1))/(y)) #endif
# endif
/* We use a macro for fd_set so that including Sockets.h afterwards #define _NFDBITS ((int)sizeof(__fd_mask) * 8) /* bits per mask */
can work. */ #if __BSD_VISIBLE
typedef struct _types_fd_set { #define NFDBITS _NFDBITS
fd_mask fds_bits[_howmany(FD_SETSIZE, NFDBITS)]; #endif
} _types_fd_set;
#define fd_set _types_fd_set #ifndef _howmany
#define _howmany(x,y) (((x) + ((y) - 1)) / (y))
#endif
# define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS))) typedef struct fd_set {
# define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS))) __fd_mask __fds_bits[_howmany(FD_SETSIZE, _NFDBITS)];
# define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS))) } fd_set;
# define FD_ZERO(p) (__extension__ (void)({ \ #if __BSD_VISIBLE
size_t __i; \ #define fds_bits __fds_bits
char *__tmp = (char *)p; \ #endif
for (__i = 0; __i < sizeof (*(p)); ++__i) \
*__tmp++ = 0; \ #define __fdset_mask(n) ((__fd_mask)1 << ((n) % _NFDBITS))
})) #define FD_CLR(n, p) ((p)->__fds_bits[(n)/_NFDBITS] &= ~__fdset_mask(n))
#if __BSD_VISIBLE
#define FD_COPY(f, t) (void)(*(t) = *(f))
#endif
#define FD_ISSET(n, p) (((p)->__fds_bits[(n)/_NFDBITS] & __fdset_mask(n)) != 0)
#define FD_SET(n, p) ((p)->__fds_bits[(n)/_NFDBITS] |= __fdset_mask(n))
#define FD_ZERO(p) do { \
fd_set *_p; \
__size_t _n; \
\
_p = (p); \
_n = _howmany(FD_SETSIZE, _NFDBITS); \
while (_n > 0) \
_p->__fds_bits[--_n] = 0; \
} while (0)
#if !defined (__INSIDE_CYGWIN_NET__) #if !defined (__INSIDE_CYGWIN_NET__)