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