• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2019 Google, Inc.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef SELECT_H__
19 #define SELECT_H__
20 
21 #include <stdlib.h>
22 #include <sys/select.h>
23 #include <sys/time.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 
27 #define str_expand(s) str(s)
28 #define str(s) #s
29 
30 #if defined(SYSCALL_SELECT_LIBC)
31 
32 // bionic and GNU libc actually use pselect6 instead, others?
33 #define SELECT_TEST_SYSCALL select
34 #define SELECT_TEST_FILENAME(x) x
35 
36 #else
37 
38 #ifndef TCONF
39 #include "test.h"
40 #endif
41 #ifndef tst_brkm
42 #include <stdio.h>
43 #define tst_brkm(a1, a2, whatever...) \
44 	{ \
45 		printf("BROK : "); \
46 		printf(whatever); \
47 		printf("\n"); \
48 		_exit(0); \
49 	}
50 #endif
51 
52 #include "lapi/syscalls.h"
53 
54 #define undefined __LTP__NR_INVALID_SYSCALL
55 
56 #ifndef __NR_select
57 #define __NR_select undefined
58 #endif
59 #if defined(__LP64__)
60 #define select_sys_select(n, inp, outp, exp, tvp) \
61 	return ltp_syscall(__NR_select, n, inp, outp, exp, tvp)
62 #else
63 struct compat_sel_arg_struct {
64 	long _n;
65 	long _inp;
66 	long _outp;
67 	long _exp;
68 	long _tvp;
69 };
70 #define select_sys_select(n, inp, outp, exp, tvp) \
71 	struct compat_sel_arg_struct arg; \
72 \
73 	arg._n = (long)n; \
74 	arg._inp = (long)inp; \
75 	arg._outp = (long)outp; \
76 	arg._exp = (long)exp; \
77 	arg._tvp = (long)tvp; \
78 	return ltp_syscall(__NR_select, &arg)
79 #endif
80 
81 #ifndef __NR__newselect
82 #define __NR__newselect undefined
83 #endif
84 #define select_sys__newselect(n, inp, outp, exp, tvp) \
85 	return ltp_syscall(__NR__newselect, n, inp, outp, exp, tvp)
86 
87 #define select_sys_pselect6(n, inp, outp, exp, tvp) \
88 	int ret; \
89 	struct timespec ts; \
90 \
91 	ts.tv_sec = tvp->tv_sec; \
92 	ts.tv_nsec = tvp->tv_usec * 1000; \
93 	ret = ltp_syscall(__NR_pselect6, n, inp, outp, exp, &ts, NULL); \
94 	tvp->tv_sec = ts.tv_sec; \
95 	tvp->tv_usec = ts.tv_nsec / 1000; \
96 	return ret
97 
98 #if defined(SYSCALL_SELECT__NEWSELECT)
99 #define SELECT_TEST_SYSCALL _newselect
100 #elif defined(SYSCALL_SELECT_SELECT)
101 #define SELECT_TEST_SYSCALL select
102 #elif defined(SYSCALL_SELECT_PSELECT6)
103 #define SELECT_TEST_SYSCALL pselect6
104 #else
105 /* automatically select between newselect, select or pselect6 if available */
106 #if __NR__newselect != __LTP__NR_INVALID_SYSCALL
107 #define SELECT_TEST_SYSCALL _newselect
108 #elif __NR_select != __LTP__NR_INVALID_SYSCALL
109 #define SELECT_TEST_SYSCALL select
110 #else
111 #define SELECT_TEST_SYSCALL pselect6
112 #endif
113 #endif
114 
115 #define __MY_select(x) select_sys_ ## x
116 #define _MY_select(x) __MY_select(x)
117 #define MY_select _MY_select(SELECT_TEST_SYSCALL)
118 
select(int __fd_count,fd_set * __read_fds,fd_set * __write_fds,fd_set * __exception_fds,struct timeval * __timeout)119 int select(int __fd_count, fd_set* __read_fds, fd_set* __write_fds,
120 	   fd_set* __exception_fds, struct timeval* __timeout)
121 {
122 	MY_select(__fd_count, __read_fds, __write_fds, __exception_fds,
123 		  __timeout);
124 }
125 
126 #define SELECT_TEST_FILENAME(x) x "_SYS_" str_expand(SELECT_TEST_SYSCALL)
127 
128 #endif /* ! SYSCALL_SELECT_LIBC */
129 
130 #endif  /* SELECT_H__ */
131