at master 103 lines 2.8 kB view raw
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 ~(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] & \ 461U << (__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(__ARCH_WANT_SYS_OLD_SELECT) && !defined(__NR__newselect) 67 struct sel_arg_struct { 68 unsigned long n; 69 fd_set *r, *w, *e; 70 struct timeval *t; 71 } arg = { .n = nfds, .r = rfds, .w = wfds, .e = efds, .t = timeout }; 72 return my_syscall1(__NR_select, &arg); 73#elif defined(__NR__newselect) 74 return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout); 75#elif defined(__NR_select) 76 return my_syscall5(__NR_select, nfds, rfds, wfds, efds, timeout); 77#elif defined(__NR_pselect6) 78 struct timespec t; 79 80 if (timeout) { 81 t.tv_sec = timeout->tv_sec; 82 t.tv_nsec = timeout->tv_usec * 1000; 83 } 84 return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL); 85#else 86 struct __kernel_timespec t; 87 88 if (timeout) { 89 t.tv_sec = timeout->tv_sec; 90 t.tv_nsec = timeout->tv_usec * 1000; 91 } 92 return my_syscall6(__NR_pselect6_time64, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL); 93#endif 94} 95 96static __attribute__((unused)) 97int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) 98{ 99 return __sysret(sys_select(nfds, rfds, wfds, efds, timeout)); 100} 101 102 103#endif /* _NOLIBC_SYS_SELECT_H */