1*b9504c9aSIlya Leoshkevich /*
2*b9504c9aSIlya Leoshkevich  * Test GDB's follow-fork-mode.
3*b9504c9aSIlya Leoshkevich  *
4*b9504c9aSIlya Leoshkevich  * fork() a chain of processes.
5*b9504c9aSIlya Leoshkevich  * Parents sends one byte to their children, and children return their
6*b9504c9aSIlya Leoshkevich  * position in the chain, in order to prove that they survived GDB's fork()
7*b9504c9aSIlya Leoshkevich  * handling.
8*b9504c9aSIlya Leoshkevich  *
9*b9504c9aSIlya Leoshkevich  * SPDX-License-Identifier: GPL-2.0-or-later
10*b9504c9aSIlya Leoshkevich  */
11*b9504c9aSIlya Leoshkevich #include <assert.h>
12*b9504c9aSIlya Leoshkevich #include <stdlib.h>
13*b9504c9aSIlya Leoshkevich #include <sys/wait.h>
14*b9504c9aSIlya Leoshkevich #include <unistd.h>
15*b9504c9aSIlya Leoshkevich 
break_after_fork(void)16*b9504c9aSIlya Leoshkevich void break_after_fork(void)
17*b9504c9aSIlya Leoshkevich {
18*b9504c9aSIlya Leoshkevich }
19*b9504c9aSIlya Leoshkevich 
main(void)20*b9504c9aSIlya Leoshkevich int main(void)
21*b9504c9aSIlya Leoshkevich {
22*b9504c9aSIlya Leoshkevich     int depth = 42, err, i, fd[2], status;
23*b9504c9aSIlya Leoshkevich     pid_t child, pid;
24*b9504c9aSIlya Leoshkevich     ssize_t n;
25*b9504c9aSIlya Leoshkevich     char b;
26*b9504c9aSIlya Leoshkevich 
27*b9504c9aSIlya Leoshkevich     for (i = 0; i < depth; i++) {
28*b9504c9aSIlya Leoshkevich         err = pipe(fd);
29*b9504c9aSIlya Leoshkevich         assert(err == 0);
30*b9504c9aSIlya Leoshkevich         child = fork();
31*b9504c9aSIlya Leoshkevich         break_after_fork();
32*b9504c9aSIlya Leoshkevich         assert(child != -1);
33*b9504c9aSIlya Leoshkevich         if (child == 0) {
34*b9504c9aSIlya Leoshkevich             close(fd[1]);
35*b9504c9aSIlya Leoshkevich 
36*b9504c9aSIlya Leoshkevich             n = read(fd[0], &b, 1);
37*b9504c9aSIlya Leoshkevich             close(fd[0]);
38*b9504c9aSIlya Leoshkevich             assert(n == 1);
39*b9504c9aSIlya Leoshkevich             assert(b == (char)i);
40*b9504c9aSIlya Leoshkevich         } else {
41*b9504c9aSIlya Leoshkevich             close(fd[0]);
42*b9504c9aSIlya Leoshkevich 
43*b9504c9aSIlya Leoshkevich             b = (char)i;
44*b9504c9aSIlya Leoshkevich             n = write(fd[1], &b, 1);
45*b9504c9aSIlya Leoshkevich             close(fd[1]);
46*b9504c9aSIlya Leoshkevich             assert(n == 1);
47*b9504c9aSIlya Leoshkevich 
48*b9504c9aSIlya Leoshkevich             pid = waitpid(child, &status, 0);
49*b9504c9aSIlya Leoshkevich             assert(pid == child);
50*b9504c9aSIlya Leoshkevich             assert(WIFEXITED(status));
51*b9504c9aSIlya Leoshkevich             return WEXITSTATUS(status) - 1;
52*b9504c9aSIlya Leoshkevich         }
53*b9504c9aSIlya Leoshkevich     }
54*b9504c9aSIlya Leoshkevich 
55*b9504c9aSIlya Leoshkevich     return depth;
56*b9504c9aSIlya Leoshkevich }
57