1 /*
2 * Test PID namespace translation
3 *
4 * Copyright (c) 2020 Ákos Uzonyi <uzonyi.akos@gmail.com>
5 * Copyright (c) 2020-2022 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 "scno.h"
13 #include "pidns.h"
14
15 #ifdef __NR_fork
16
17 # include <errno.h>
18 # include <limits.h>
19 # include <sched.h>
20 # include <signal.h>
21 # include <stdio.h>
22 # include <stdlib.h>
23 # include <sys/wait.h>
24 # include <unistd.h>
25 # include <linux/sched.h>
26 # include <linux/nsfs.h>
27
28 static int
29 fork_chain(int depth)
30 {
31 if (!depth)
32 return 0;
33
34 int pid = syscall(__NR_fork);
35 if (pid < 0)
36 return errno;
37
38 if (!pid)
39 _exit(fork_chain(depth - 1));
40
41 int status;
42 if (waitpid(pid, &status, 0) < 0) {
43 if (errno == ECHILD)
44 _exit(fork_chain(depth - 1));
45 return errno;
46 }
47
48 if (!WIFEXITED(status))
49 return -1;
50
51 return WEXITSTATUS(status);
52 }
53
54 int main(void)
55 {
56 check_ns_ioctl();
57
58 if (unshare(CLONE_NEWPID | CLONE_NEWUSER) < 0) {
59 if (errno == EPERM)
60 perror_msg_and_skip("unshare");
61
62 perror_msg_and_fail("unshare");
63 }
64
65 errno = fork_chain(2);
66 if (errno)
67 perror_msg_and_fail("fork_chain");
68 return 0;
69 }
70
71 #else
72
73 SKIP_MAIN_UNDEFINED("__NR_fork")
74
75 #endif