• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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