Skip to content

Commit c92cf08

Browse files
committed
[ABI BREAK]: abis: Fix definition of fd_set
1 parent 3208ea1 commit c92cf08

File tree

5 files changed

+24
-12
lines changed

5 files changed

+24
-12
lines changed

ABI_BREAKS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ This document lists the ABI breaks that were made in each mlibc major version.
2727
- [#1460](https://github.com/managarm/mlibc/pull/1460): `useconds_t` was turned into a 32-bit value, as it only needs to hold microsecond values worth up to a second.
2828
- [#1492](https://github.com/managarm/mlibc/pull/1492): changes the values of `LC_*` macros and `nl_item` values to match glibc, so that glibc locale files can be consumed.
2929
- [#1492](https://github.com/managarm/mlibc/pull/1492): fix `struct epoll_event` alignment on x86
30+
- [#1658](https://github.com/managarm/mlibc/pull/1658): fix incorrect definition of `struct fd_set`
3031

3132
## Version 6
3233

abis/ironclad/fd_set.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55

66
#define FD_SETSIZE 1024
77

8+
typedef __mlibc_uint8 __fd_mask;
9+
#define __NFDBITS (8 * (int) sizeof (__fd_mask))
10+
811
typedef struct __attribute__((__aligned__(__alignof__(long)))) {
9-
__mlibc_uint8 fds_bits[128];
12+
__fd_mask fds_bits[FD_SETSIZE / __NFDBITS];
1013
} fd_set;
1114

1215
#endif /* _ABIBITS_FD_SET_H */

abis/linux/fd_set.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@
55

66
#define FD_SETSIZE 1024
77

8-
typedef struct __attribute__((__aligned__(__alignof__(long)))) {
9-
__mlibc_uint8 fds_bits[128];
8+
typedef long int __fd_mask;
9+
#define __NFDBITS (8 * (int) sizeof (__fd_mask))
10+
11+
typedef struct {
12+
/* libtirpc reaches into fds_bits directly, so we must keep the name and type exactly as expected.
13+
* This now matches the definition in sys/select.h from glibc. */
14+
__fd_mask fds_bits[FD_SETSIZE / __NFDBITS];
1015
} fd_set;
1116

1217
#endif /* _ABIBITS_FD_SET_H */

options/posix/generic/sys-select.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <bit>
2+
#include <type_traits>
13

24
#include <string.h>
35
#include <sys/select.h>
@@ -9,17 +11,21 @@
911

1012
#include <mlibc/posix-sysdeps.hpp>
1113

14+
using fd_mask_unsigned = std::make_unsigned_t<__fd_mask>;
15+
16+
#define FD_MASK(n) (fd_mask_unsigned{1} << (n))
17+
1218
void __FD_CLR(int fd, fd_set *set) {
13-
__ensure(fd < FD_SETSIZE);
14-
set->fds_bits[fd / 8] &= ~(1 << (fd % 8));
19+
__ensure(fd < FD_SETSIZE);
20+
set->fds_bits[fd / NFDBITS] &= std::bit_cast<fd_mask>(~FD_MASK(fd % NFDBITS));
1521
}
1622
int __FD_ISSET(int fd, fd_set *set) {
17-
__ensure(fd < FD_SETSIZE);
18-
return set->fds_bits[fd / 8] & (1 << (fd % 8));
23+
__ensure(fd < FD_SETSIZE);
24+
return (std::bit_cast<fd_mask_unsigned>(set->fds_bits[fd / NFDBITS]) & FD_MASK(fd % NFDBITS)) != 0;
1925
}
2026
void __FD_SET(int fd, fd_set *set) {
21-
__ensure(fd < FD_SETSIZE);
22-
set->fds_bits[fd / 8] |= 1 << (fd % 8);
27+
__ensure(fd < FD_SETSIZE);
28+
set->fds_bits[fd / NFDBITS] = std::bit_cast<fd_mask>(std::bit_cast<fd_mask_unsigned>(set->fds_bits[fd / NFDBITS]) | FD_MASK(fd % NFDBITS));
2329
}
2430
void __FD_ZERO(fd_set *set) {
2531
memset(set->fds_bits, 0, sizeof(fd_set));

options/posix/include/sys/select.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414
extern "C" {
1515
#endif
1616

17-
typedef long int __fd_mask;
18-
#define __NFDBITS (8 * (int) sizeof (__fd_mask))
19-
2017
#if defined(_DEFAULT_SOURCE)
2118
typedef __fd_mask fd_mask;
2219
#define NFDBITS __NFDBITS

0 commit comments

Comments
 (0)