projects/linux·blob master · refs

94 lines · 2.3 KiB

1/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2
3#include "../nolibc.h"
4
5#ifndef _NOLIBC_SYS_SELECT_H
6#define _NOLIBC_SYS_SELECT_H
7
8#include <linux/time.h>
9#include <linux/unistd.h>
10
11/* commonly an fd_set represents 256 FDs */
12#ifndef FD_SETSIZE
13#define FD_SETSIZE 256
14#endif
15
16#define FD_SETIDXMASK (8 * sizeof(unsigned long))
17#define FD_SETBITMASK (8 * sizeof(unsigned long)-1)
18
19/* for select() */
20typedef struct {
21 unsigned long fds[(FD_SETSIZE + FD_SETBITMASK) / FD_SETIDXMASK];
22} fd_set;
23
24#define FD_CLR(fd, set) do { \
25 fd_set *__set = (set); \
26 int __fd = (fd); \
27 if (__fd >= 0) \
28 __set->fds[__fd / FD_SETIDXMASK] &= \
29 ~(1UL << (__fd & FD_SETBITMASK)); \
30 } while (0)
31
32#define FD_SET(fd, set) do { \
33 fd_set *__set = (set); \
34 int __fd = (fd); \
35 if (__fd >= 0) \
36 __set->fds[__fd / FD_SETIDXMASK] |= \
37 1UL << (__fd & FD_SETBITMASK); \
38 } while (0)
39
40#define FD_ISSET(fd, set) ({ \
41 fd_set *__set = (set); \
42 int __fd = (fd); \
43 int __r = 0; \
44 if (__fd >= 0) \
45 __r = !!(__set->fds[__fd / FD_SETIDXMASK] & \
461UL << (__fd & FD_SETBITMASK)); \
47 __r; \
48 })
49
50#define FD_ZERO(set) do { \
51 fd_set *__set = (set); \
52 int __idx; \
53 int __size = (FD_SETSIZE+FD_SETBITMASK) / FD_SETIDXMASK;\
54 for (__idx = 0; __idx < __size; __idx++) \
55 __set->fds[__idx] = 0; \
56 } while (0)
57
58/*
59 * int select(int nfds, fd_set *read_fds, fd_set *write_fds,
60 * fd_set *except_fds, struct timeval *timeout);
61 */
62
63static __attribute__((unused))
64int _sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)
65{
66#if defined(__NR_pselect6_time64)
67 struct __kernel_timespec t;
68
69 if (timeout) {
70 t.tv_sec = timeout->tv_sec;
71 t.tv_nsec = (uint32_t)timeout->tv_usec * 1000;
72 }
73 return __nolibc_syscall6(__NR_pselect6_time64, nfds, rfds, wfds, efds,
74 timeout ? &t : NULL, NULL);
75#else
76 struct __kernel_old_timespec t;
77
78 if (timeout) {
79 t.tv_sec = timeout->tv_sec;
80 t.tv_nsec = (uint32_t)timeout->tv_usec * 1000;
81 }
82 return __nolibc_syscall6(__NR_pselect6, nfds, rfds, wfds, efds,
83 timeout ? &t : NULL, NULL);
84#endif
85}
86
87static __attribute__((unused))
88int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)
89{
90 return __sysret(_sys_select(nfds, rfds, wfds, efds, timeout));
91}
92
93
94#endif /* _NOLIBC_SYS_SELECT_H */