1 /*
2 * Check handling of CLONE_PARENT'ed processes.
3 *
4 * Copyright (c) 2017-2020 The strace developers.
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "tests.h"
11
12 #include <errno.h>
13 #include <sched.h>
14 #include <signal.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <sys/wait.h>
18 #include <unistd.h>
19
20 #ifndef QUIET_MSG
21 # define QUIET_MSG 0
22 #endif
23
24 static int
25 child(void *const arg)
26 {
27 return 42;
28 }
29
30 #ifdef IA64
31 extern int __clone2(int (*)(void *), void *, size_t, int, void *, ...);
32 # define do_clone(fn_, stack_, size_, flags_, arg_, ...) \
33 __clone2((fn_), (stack_), (size_), (flags_), (arg_), ## __VA_ARGS__)
34 #else
35 # define do_clone(fn_, stack_, size_, flags_, arg_, ...) \
36 clone((fn_), (stack_), (flags_), (arg_), ## __VA_ARGS__)
37 #endif
38
39 int
40 main(void)
41 {
42 const unsigned long child_stack_size = get_page_size();
43 void *const child_stack =
44 tail_alloc(child_stack_size * 2) + child_stack_size;
45
46 const pid_t pid = do_clone(child, child_stack, child_stack_size,
47 CLONE_PARENT | SIGCHLD, 0);
48 if (pid < 0)
49 perror_msg_and_fail("clone");
50
51 int status;
52 if (wait(&status) >= 0)
53 error_msg_and_fail("unexpected return code from wait");
54
55 while (!kill(pid, 0))
56 ;
57 if (errno != ESRCH)
58 perror_msg_and_fail("kill");
59
60 FILE *const fp = fdopen(3, "a");
61 if (!fp)
62 perror_msg_and_fail("fdopen");
63 #if !QUIET_MSG
64 if (fprintf(fp, "%s: Exit of unknown pid %d ignored\n",
65 getenv("STRACE_EXE") ?: "strace", pid) < 0)
66 perror_msg_and_fail("fprintf");
67 #endif
68
69 #if !QUIET_MSG
70 puts("+++ exited with 0 +++");
71 #endif
72 return 0;
73 }