1 /*
2 * Copyright (C) 2019 Cyril Hrubis <chrubis@suse.cz>
3 */
4
5 #ifndef SELECT_VAR__
6 #define SELECT_VAR__
7
8 #include "lapi/syscalls.h"
9 #include "tst_timer.h"
10
11 struct compat_sel_arg_struct {
12 long _n;
13 long _inp;
14 long _outp;
15 long _exp;
16 long _tvp;
17 };
18
19 #define GLIBC_SELECT_VARIANT 0
20
do_select_faulty_to(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout,int faulty_to)21 static int do_select_faulty_to(int nfds, fd_set *readfds, fd_set *writefds,
22 fd_set *exceptfds, struct timeval *timeout, int faulty_to)
23 {
24 switch (tst_variant) {
25 case 0:
26 return select(nfds, readfds, writefds, exceptfds, timeout);
27 break;
28 case 1: {
29 #ifdef __LP64__
30 return tst_syscall(__NR_select, nfds, readfds, writefds, exceptfds, timeout);
31 #else
32 struct compat_sel_arg_struct arg = {
33 ._n = (long)nfds,
34 ._inp = (long)readfds,
35 ._outp = (long)writefds,
36 ._exp = (long)exceptfds,
37 ._tvp = (long)timeout,
38 };
39
40 return tst_syscall(__NR_select, &arg);
41 #endif /* __LP64__ */
42 }
43 case 2: {
44 int ret;
45 struct __kernel_old_timespec _ts;
46 void *ts;
47
48 if (faulty_to) {
49 ts = timeout;
50 } else {
51 ts = &_ts;
52 _ts.tv_sec = timeout->tv_sec;
53 _ts.tv_nsec = timeout->tv_usec * 1000;
54 }
55
56 ret = tst_syscall(__NR_pselect6, nfds, readfds, writefds, exceptfds, ts, NULL);
57 if (!faulty_to) {
58 timeout->tv_sec = _ts.tv_sec;
59 timeout->tv_usec = _ts.tv_nsec / 1000;
60 }
61 return ret;
62 }
63 case 3: {
64 int ret = 0;
65 #if (__NR_pselect6_time64 != __LTP__NR_INVALID_SYSCALL)
66 struct __kernel_timespec _ts;
67 void *ts;
68
69 if (faulty_to) {
70 ts = timeout;
71 } else {
72 ts = &_ts;
73 _ts.tv_sec = timeout->tv_sec;
74 _ts.tv_nsec = timeout->tv_usec * 1000;
75 }
76
77 ret = tst_syscall(__NR_pselect6_time64, nfds, readfds, writefds, exceptfds, ts, NULL);
78 if (!faulty_to) {
79 timeout->tv_sec = _ts.tv_sec;
80 timeout->tv_usec = _ts.tv_nsec / 1000;
81 }
82 #else
83 tst_brk(TCONF, "__NR_pselect6 time64 variant not supported");
84 #endif
85 return ret;
86 }
87 case 4:
88 #ifdef __NR__newselect
89 return tst_syscall(__NR__newselect, nfds, readfds, writefds, exceptfds, timeout);
90 #else
91 tst_brk(TCONF, "__NR__newselect not implemented");
92 #endif
93 break;
94 }
95
96 return -1;
97 }
98
do_select(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout)99 static inline int do_select(int nfds, fd_set *readfds, fd_set *writefds,
100 fd_set *exceptfds, struct timeval *timeout)
101 {
102 return do_select_faulty_to(nfds, readfds, writefds, exceptfds, timeout, 0);
103 }
104
select_info(void)105 static void select_info(void)
106 {
107 switch (tst_variant) {
108 case 0:
109 tst_res(TINFO, "Testing libc select()");
110 break;
111 case 1:
112 tst_res(TINFO, "Testing SYS_select syscall");
113 break;
114 case 2:
115 tst_res(TINFO, "Testing SYS_pselect6 syscall");
116 break;
117 case 3:
118 tst_res(TINFO, "Testing SYS_pselect6 time64 syscall");
119 break;
120 case 4:
121 tst_res(TINFO, "Testing SYS__newselect syscall");
122 break;
123 }
124 }
125
126 #define TEST_VARIANTS 5
127
128 #endif /* SELECT_VAR__ */
129