1570af302Sopenharmony_ci#include <sys/select.h>
2570af302Sopenharmony_ci#include <signal.h>
3570af302Sopenharmony_ci#include <stdint.h>
4570af302Sopenharmony_ci#include <errno.h>
5570af302Sopenharmony_ci#include "syscall.h"
6570af302Sopenharmony_ci
7570af302Sopenharmony_ci#define IS32BIT(x) !((x)+0x80000000ULL>>32)
8570af302Sopenharmony_ci#define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63))
9570af302Sopenharmony_ci
10570af302Sopenharmony_ciint select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, struct timeval *restrict tv)
11570af302Sopenharmony_ci{
12570af302Sopenharmony_ci	time_t s = tv ? tv->tv_sec : 0;
13570af302Sopenharmony_ci	suseconds_t us = tv ? tv->tv_usec : 0;
14570af302Sopenharmony_ci	long ns;
15570af302Sopenharmony_ci	const time_t max_time = (1ULL<<8*sizeof(time_t)-1)-1;
16570af302Sopenharmony_ci
17570af302Sopenharmony_ci	if (s<0 || us<0) return __syscall_ret(-EINVAL);
18570af302Sopenharmony_ci	if (us/1000000 > max_time - s) {
19570af302Sopenharmony_ci		s = max_time;
20570af302Sopenharmony_ci		us = 999999;
21570af302Sopenharmony_ci		ns = 999999999;
22570af302Sopenharmony_ci	} else {
23570af302Sopenharmony_ci		s += us/1000000;
24570af302Sopenharmony_ci		us %= 1000000;
25570af302Sopenharmony_ci		ns = us*1000;
26570af302Sopenharmony_ci	}
27570af302Sopenharmony_ci
28570af302Sopenharmony_ci#ifdef SYS_pselect6_time64
29570af302Sopenharmony_ci	int r = -ENOSYS;
30570af302Sopenharmony_ci	if (SYS_pselect6 == SYS_pselect6_time64 || !IS32BIT(s))
31570af302Sopenharmony_ci		r = __syscall_cp(SYS_pselect6_time64, n, rfds, wfds, efds,
32570af302Sopenharmony_ci			tv ? ((long long[]){s, ns}) : 0,
33570af302Sopenharmony_ci			((syscall_arg_t[]){ 0, _NSIG/8 }));
34570af302Sopenharmony_ci	if (SYS_pselect6 == SYS_pselect6_time64 || r!=-ENOSYS)
35570af302Sopenharmony_ci		return __syscall_ret(r);
36570af302Sopenharmony_ci	s = CLAMP(s);
37570af302Sopenharmony_ci#endif
38570af302Sopenharmony_ci#ifdef SYS_select
39570af302Sopenharmony_ci	return syscall_cp(SYS_select, n, rfds, wfds, efds,
40570af302Sopenharmony_ci#ifdef __LITEOS_A__
41570af302Sopenharmony_ci		tv ? ((long long[]){s, us}) : 0);
42570af302Sopenharmony_ci#else
43570af302Sopenharmony_ci		tv ? ((long[]){s, us}) : 0);
44570af302Sopenharmony_ci#endif
45570af302Sopenharmony_ci#else
46570af302Sopenharmony_ci	return syscall_cp(SYS_pselect6, n, rfds, wfds, efds,
47570af302Sopenharmony_ci#ifdef __LITEOS_A__
48570af302Sopenharmony_ci		tv ? ((long long[]){s, ns}) : 0, ((syscall_arg_t[]){ 0, _NSIG/8 }));
49570af302Sopenharmony_ci#else
50570af302Sopenharmony_ci		tv ? ((long[]){s, ns}) : 0, ((syscall_arg_t[]){ 0, _NSIG/8 }));
51570af302Sopenharmony_ci#endif
52570af302Sopenharmony_ci#endif
53570af302Sopenharmony_ci}
54