1 /*
2 * Invoke a socket syscall, either directly or via __NR_socketcall.
3 *
4 * Copyright (c) 2016-2018 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2016-2021 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "tests.h"
12 #include <errno.h>
13 #include <unistd.h>
14 #include "scno.h"
15
16 /*
17 * Invoke a socket syscall, either directly or via __NR_socketcall.
18 * if nr == -1, no direct syscall invocation will be made.
19 */
20 int
21 socketcall(const int nr, const int call,
22 long a1, long a2, long a3, long a4, long a5)
23 {
24 int rc = -1;
25 errno = ENOSYS;
26
27 #ifdef __NR_socketcall
28 static int have_socketcall = -1;
29
30 if (have_socketcall < 0) {
31 if (syscall(__NR_socketcall, 0L, 0L, 0L, 0L, 0L) < 0
32 && EINVAL == errno) {
33 have_socketcall = 1;
34 } else {
35 have_socketcall = 0;
36 }
37 }
38
39 if (have_socketcall) {
40 const long args[] = { a1, a2, a3, a4, a5 };
41 rc = syscall(__NR_socketcall, call, args);
42 } else
43 #endif
44 {
45 if (nr != -1)
46 rc = syscall(nr, a1, a2, a3, a4, a5);
47 }
48
49 return rc;
50 }