On 2025-07-09 17:55:11+0200, Benjamin Berg wrote:
From: Benjamin Berg benjamin.berg@intel.com
The FD_* macros are assuming a specific type for the bitset. Add new macros that introspect the type of the passed variable in order to know the size of the bitset. This way the same macros can be used for other purposes.
Signed-off-by: Benjamin Berg benjamin.berg@intel.com
tools/include/nolibc/types.h | 67 +++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 31 deletions(-)
diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h index 16c6e9ec9451..3100771e21ad 100644 --- a/tools/include/nolibc/types.h +++ b/tools/include/nolibc/types.h @@ -115,48 +115,53 @@ #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 -#define FD_SETIDXMASK (8 * sizeof(unsigned long)) -#define FD_SETBITMASK (8 * sizeof(unsigned long)-1)
-/* for select() */ -typedef struct {
- unsigned long fds[(FD_SETSIZE + FD_SETBITMASK) / FD_SETIDXMASK];
-} fd_set;
-#define FD_CLR(fd, set) do { \
fd_set *__set = (set); \
int __fd = (fd); \
if (__fd >= 0) \
__set->fds[__fd / FD_SETIDXMASK] &= \
~(1U << (__fd & FD_SETBITMASK)); \
+#define BITSET_CLR(num, set) do { \
__NOLIBC_BITMASK_CLEAR()
To avoid conflicts with user code, being clear about the intent and having some constency with the kernel code.
__typeof__(set) *__set = &(set); \
int __num = (num); \
if (__num >= 0 && __num < 8 * (ssize_t)sizeof(*__set)) \
(*__set)[__num / (8 * sizeof(set[0]))] &= \
} while (0)~(1U << (__num % (8 * sizeof(**__set)))); \
-#define FD_SET(fd, set) do { \
fd_set *__set = (set); \
int __fd = (fd); \
if (__fd >= 0) \
__set->fds[__fd / FD_SETIDXMASK] |= \
1 << (__fd & FD_SETBITMASK); \
+#define BITSET_SET(num, set) do { \
__typeof__(set) *__set = &(set); \
int __num = (num); \
if (__num >= 0 && __num < 8 * (ssize_t)sizeof(*__set)) \
(*__set)[__num / (8 * sizeof(set[0]))] |= \
} while (0)1U << (__num % (8 * sizeof(**__set))); \
-#define FD_ISSET(fd, set) ({ \
fd_set *__set = (set); \
int __fd = (fd); \
+#define BITSET_ISSET(num, set) ({ \
__NOLIBC_BITMASK_TEST()
__typeof__(set) *__set = &(set); \
int __r = 0; \int __num = (num); \
if (__fd >= 0) \
__r = !!(__set->fds[__fd / FD_SETIDXMASK] & \
-1U << (__fd & FD_SETBITMASK)); \
__r; \
if (__num >= 0 && __num < 8 * (ssize_t)sizeof(*__set)) \
__r = (*__set)[__num / (8 * sizeof(set[0]))] & \
(1U << (__num % (8 * sizeof(**__set)))); \
})!!__r; \
-#define FD_ZERO(set) do { \
fd_set *__set = (set); \
+#define BITSET_ZERO(set) do { \
int __idx; \__typeof__(set) *__set = &(set); \
int __size = (FD_SETSIZE+FD_SETBITMASK) / FD_SETIDXMASK;\
for (__idx = 0; __idx < __size; __idx++) \int __size = sizeof(*__set) / sizeof(**__set); \
__set->fds[__idx] = 0; \
} while (0)(*__set)[__idx] = 0; \
+#define FD_SETIDXMASK (8 * sizeof(unsigned long)) +#define FD_SETBITMASK (8 * sizeof(unsigned long)-1)
+/* for select() */ +typedef struct {
- unsigned long fds[(FD_SETSIZE + FD_SETBITMASK) / FD_SETIDXMASK];
+} fd_set;
+#define FD_CLR(fd, set) BITSET_CLR(fd, (set)->fds) +#define FD_SET(fd, set) BITSET_SET(fd, (set)->fds) +#define FD_ISSET(fd, set) BITSET_ISSET(fd, (set)->fds) +#define FD_ZERO(set) BITSET_ZERO((set)->fds)
These could be inline function I think.
/* for getdents64() */ struct linux_dirent64 { uint64_t d_ino; -- 2.50.0