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() */ 20 typedef 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 ~(1U << (__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 1 << (__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] & \ 46 1U << (__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 63 static __attribute__((unused)) 64 int 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 my_syscall6(__NR_pselect6_time64, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL); 74 #else 75 struct __kernel_old_timespec t; 76 77 if (timeout) { 78 t.tv_sec = timeout->tv_sec; 79 t.tv_nsec = (uint32_t)timeout->tv_usec * 1000; 80 } 81 return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL); 82 #endif 83 } 84 85 static __attribute__((unused)) 86 int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) 87 { 88 return __sysret(sys_select(nfds, rfds, wfds, efds, timeout)); 89 } 90 91 92 #endif /* _NOLIBC_SYS_SELECT_H */ 93