1 /*
2 * Check decoding of dup2 syscall.
3 *
4 * Copyright (c) 2016-2023 The strace developers.
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "tests.h"
11 #include "scno.h"
12
13 #ifdef __NR_dup2
14
15 # include <stdio.h>
16 # include <unistd.h>
17
18 # ifndef FD0_PATH
19 # define FD0_PATH ""
20 # endif
21 # ifndef FD9_PATH
22 # define FD9_PATH ""
23 # endif
24 # ifndef SKIP_IF_PROC_IS_UNAVAILABLE
25 # define SKIP_IF_PROC_IS_UNAVAILABLE
26 # endif
27
28 # ifndef PATH_TRACING
29 # define PATH_TRACING 0
30 # endif
31 # ifndef TRACE_FDS
32 # define TRACE_FDS 0
33 # endif
34 # ifndef TRACE_FD_0
35 # define TRACE_FD_0 (!TRACE_FDS && !PATH_TRACING)
36 # endif
37 # ifndef TRACE_OTHER_FDS
38 # define TRACE_OTHER_FDS (!TRACE_FDS && !PATH_TRACING)
39 # endif
40 # ifndef TRACE_FD_9
41 # define TRACE_FD_9 (!TRACE_FDS && !PATH_TRACING)
42 # endif
43
44
45 static const char *errstr;
46
47 static long
48 k_dup2(const unsigned int fd1, const unsigned int fd2)
49 {
50 const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
51 const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
52 const kernel_ulong_t arg1 = fill | fd1;
53 const kernel_ulong_t arg2 = fill | fd2;
54 const long rc = syscall(__NR_dup2, arg1, arg2, bad, bad, bad, bad);
55 errstr = sprintrc(rc);
56 return rc;
57 }
58
59 int
60 main(void)
61 {
62 SKIP_IF_PROC_IS_UNAVAILABLE;
63
64 int fd0 = dup(0);
65 int fd9 = dup(9);
66
67 if (k_dup2(0, 0))
68 perror_msg_and_skip("dup2");
69 # if TRACE_FD_0
70 printf("dup2(0" FD0_PATH ", 0" FD0_PATH ") = 0" FD0_PATH "\n");
71 # endif
72
73 k_dup2(-1, -2);
74 # if !PATH_TRACING && !TRACE_FDS
75 printf("dup2(-1, -2) = %s\n", errstr);
76 # endif
77
78 k_dup2(-2, -1);
79 # if !PATH_TRACING && !TRACE_FDS
80 printf("dup2(-2, -1) = %s\n", errstr);
81 # endif
82
83 k_dup2(-3, 0);
84 # if TRACE_FD_0
85 printf("dup2(-3, 0" FD0_PATH ") = %s\n", errstr);
86 # endif
87
88 k_dup2(0, -4);
89 # if TRACE_FD_0
90 printf("dup2(0" FD0_PATH ", -4) = %s\n", errstr);
91 # endif
92
93 k_dup2(-5, 9);
94 # if PATH_TRACING || TRACE_FD_9
95 printf("dup2(-5, 9" FD9_PATH ") = %s\n", errstr);
96 # endif
97
98 k_dup2(9, -6);
99 # if PATH_TRACING || TRACE_FD_9
100 printf("dup2(9" FD9_PATH ", -6) = %s\n", errstr);
101 # endif
102
103 k_dup2(9, 9);
104 # if PATH_TRACING || TRACE_FD_9
105 printf("dup2(9" FD9_PATH ", 9" FD9_PATH ") = 9" FD9_PATH "\n");
106 # endif
107
108 k_dup2(0, fd0);
109 # if TRACE_FD_0
110 printf("dup2(0" FD0_PATH ", %d" FD0_PATH ") = %d" FD0_PATH "\n",
111 fd0, fd0);
112 # endif
113
114 k_dup2(fd0, fd9);
115 # if PATH_TRACING || TRACE_OTHER_FDS
116 printf("dup2(%d" FD0_PATH ", %d" FD9_PATH ") = %d" FD0_PATH "\n",
117 fd0, fd9, fd9);
118 # endif
119
120 k_dup2(fd0, fd9);
121 # if TRACE_OTHER_FDS
122 printf("dup2(%d" FD0_PATH ", %d" FD0_PATH ") = %d" FD0_PATH "\n",
123 fd0, fd9, fd9);
124 # endif
125
126 k_dup2(9, fd9);
127 # if PATH_TRACING || TRACE_FD_9 || TRACE_OTHER_FDS
128 printf("dup2(9" FD9_PATH ", %d" FD0_PATH ") = %d" FD9_PATH "\n",
129 fd9, fd9);
130 # endif
131
132 k_dup2(0, fd9);
133 # if PATH_TRACING || TRACE_FD_0
134 printf("dup2(0" FD0_PATH ", %d" FD9_PATH ") = %d" FD0_PATH "\n",
135 fd9, fd9);
136 # endif
137
138 k_dup2(9, fd0);
139 # if PATH_TRACING || TRACE_FD_9 || TRACE_OTHER_FDS
140 printf("dup2(9" FD9_PATH ", %d" FD0_PATH ") = %d" FD9_PATH "\n",
141 fd0, fd0);
142 # endif
143
144 close(fd0);
145 close(fd9);
146
147 k_dup2(0, fd0);
148 # if TRACE_FD_0
149 printf("dup2(0" FD0_PATH ", %d) = %d" FD0_PATH "\n",
150 fd0, fd0);
151 # endif
152
153 k_dup2(9, fd9);
154 # if PATH_TRACING || TRACE_FD_9 || TRACE_OTHER_FDS
155 printf("dup2(9" FD9_PATH ", %d) = %d" FD9_PATH "\n",
156 fd9, fd9);
157 # endif
158
159 puts("+++ exited with 0 +++");
160 return 0;
161 }
162
163 #else
164
165 SKIP_MAIN_UNDEFINED("__NR_dup2")
166
167 #endif