1c03b94e9Schristos /* This testcase is part of GDB, the GNU debugger. 2c03b94e9Schristos 3*1424dfb3Schristos Copyright 2015-2020 Free Software Foundation, Inc. 4c03b94e9Schristos 5c03b94e9Schristos This program is free software; you can redistribute it and/or modify 6c03b94e9Schristos it under the terms of the GNU General Public License as published by 7c03b94e9Schristos the Free Software Foundation; either version 3 of the License, or 8c03b94e9Schristos (at your option) any later version. 9c03b94e9Schristos 10c03b94e9Schristos This program is distributed in the hope that it will be useful, 11c03b94e9Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 12c03b94e9Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13c03b94e9Schristos GNU General Public License for more details. 14c03b94e9Schristos 15c03b94e9Schristos You should have received a copy of the GNU General Public License 16c03b94e9Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17c03b94e9Schristos 18c03b94e9Schristos #include <unistd.h> 19c03b94e9Schristos #include <stdio.h> 20c03b94e9Schristos #include <sys/types.h> 21c03b94e9Schristos #include <sys/wait.h> 2207163879Schristos #include <errno.h> 23*1424dfb3Schristos #include <signal.h> 24c03b94e9Schristos 25c03b94e9Schristos int save_parent; 26c03b94e9Schristos 2707163879Schristos /* Variable set by GDB. If true, then a fork child (or parent) exits 2807163879Schristos if its parent (or child) exits. Otherwise the process waits 2907163879Schristos forever until either GDB or the alarm kills it. */ 3007163879Schristos volatile int exit_if_relative_exits = 0; 3107163879Schristos 32c03b94e9Schristos /* The fork child. Just runs forever. */ 33c03b94e9Schristos 34c03b94e9Schristos static int fork_child(void)35c03b94e9Schristosfork_child (void) 36c03b94e9Schristos { 3707163879Schristos /* Don't run forever. */ 3807163879Schristos alarm (180); 3907163879Schristos 40c03b94e9Schristos while (1) 41c03b94e9Schristos { 4207163879Schristos if (exit_if_relative_exits) 4307163879Schristos { 44c03b94e9Schristos sleep (1); 45c03b94e9Schristos 46c03b94e9Schristos /* Exit if GDB kills the parent. */ 47c03b94e9Schristos if (getppid () != save_parent) 48c03b94e9Schristos break; 49c03b94e9Schristos if (kill (getppid (), 0) != 0) 50c03b94e9Schristos break; 51c03b94e9Schristos } 5207163879Schristos else 5307163879Schristos pause (); 5407163879Schristos } 55c03b94e9Schristos 56c03b94e9Schristos return 0; 57c03b94e9Schristos } 58c03b94e9Schristos 5907163879Schristos /* The fork parent. Just runs forever. */ 60c03b94e9Schristos 61c03b94e9Schristos static int fork_parent(void)62c03b94e9Schristosfork_parent (void) 63c03b94e9Schristos { 6407163879Schristos /* Don't run forever. */ 6507163879Schristos alarm (180); 6607163879Schristos 6707163879Schristos while (1) 6807163879Schristos { 6907163879Schristos if (exit_if_relative_exits) 7007163879Schristos { 7107163879Schristos int res = wait (NULL); 7207163879Schristos if (res == -1 && errno == EINTR) 7307163879Schristos continue; 7407163879Schristos else if (res == -1) 75c03b94e9Schristos { 76c03b94e9Schristos perror ("wait"); 77c03b94e9Schristos return 1; 78c03b94e9Schristos } 7907163879Schristos else 8007163879Schristos return 0; 8107163879Schristos } 8207163879Schristos else 8307163879Schristos pause (); 8407163879Schristos } 85c03b94e9Schristos 86c03b94e9Schristos return 0; 87c03b94e9Schristos } 88c03b94e9Schristos 89c03b94e9Schristos int main(void)90c03b94e9Schristosmain (void) 91c03b94e9Schristos { 92c03b94e9Schristos pid_t pid; 93c03b94e9Schristos 94c03b94e9Schristos save_parent = getpid (); 95c03b94e9Schristos 96c03b94e9Schristos /* The parent and child should basically run forever without 97c03b94e9Schristos tripping on any debug event. We want to check that GDB updates 98c03b94e9Schristos the parent and child running states correctly right after the 99c03b94e9Schristos fork. */ 100c03b94e9Schristos pid = fork (); 101c03b94e9Schristos if (pid > 0) 102c03b94e9Schristos return fork_parent (); 103c03b94e9Schristos else if (pid == 0) 104c03b94e9Schristos return fork_child (); 105c03b94e9Schristos else 106c03b94e9Schristos { 107c03b94e9Schristos perror ("fork"); 108c03b94e9Schristos return 1; 109c03b94e9Schristos } 110c03b94e9Schristos } 111