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