1 // forktest.cpp Copyright (C) 2016-2020 Codemist
2
3 //
4 // This file is NOT part of CSL. It is a test file used while testing
5 // development of support for any hypothetical future concurrency schemes.
6 //
7
8 #include <sys/types.h>
9 #include <unistd.h>
10 #ifdef WIN32
11 #define SIGKILL 9
12 #else
13 #include <sys/wait.h>
14 #endif
15 #include <csignal>
16 #include <cerrno>
17 #include <cstdio>
18 #include <cstdlib>
19
20 /**************************************************************************
21 * Copyright (C) 2020, Codemist. A C Norman *
22 * *
23 * Redistribution and use in source and binary forms, with or without *
24 * modification, are permitted provided that the following conditions are *
25 * met: *
26 * *
27 * * Redistributions of source code must retain the relevant *
28 * copyright notice, this list of conditions and the following *
29 * disclaimer. *
30 * * Redistributions in binary form must reproduce the above *
31 * copyright notice, this list of conditions and the following *
32 * disclaimer in the documentation and/or other materials provided *
33 * with the distribution. *
34 * *
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
36 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
37 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
38 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
39 * COPYRIGHT OWNERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
40 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
41 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS *
42 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *
43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
44 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF *
45 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
46 * DAMAGE. *
47 *************************************************************************/
48
49 // $Id: forktest.cpp 5433 2020-10-15 21:09:02Z arthurcnorman $
50
51
52 volatile int a = 0;
53
worry(int n)54 void worry(int n)
55 { int i, j;
56 for (j=0; j<100; j++)
57 for (i=0; i<10000000*n; i++) a++;
58 }
59
main(int argc,char * argv[])60 int main(int argc, char *argv[])
61 { pid_t pid1, pid2, pidx, pidy;
62 int status;
63 pid1 = fork();
64 if (pid1 < 0)
65 { std::printf("Fork 1 failed\n");
66 }
67 else if (pid1 == 0)
68 { // TASK 1
69 std::printf("Task 1 starting\n");
70 worry(argc+5);
71 std::printf("Task 1 has had %d seconds\n", argc+5);
72 std::exit(0);
73 }
74 else
75 { std::printf("Task 1 has pid %d\n", pid1);
76 pid2 = fork();
77 if (pid2 < 0)
78 { std::printf("Fork 2 failed\n");
79 kill(pid1, SIGKILL);
80 waitpid(pid1, &status, 0);
81 std::printf("Task 1 killed\n");
82 }
83 else if (pid2 == 0)
84 { // TASK 2
85 std::printf("Task 2 starting\n");
86 worry(7);
87 std::printf("Task 2 has had 7 seconds\n");
88 std::exit(0);
89 }
90 else
91 { std::printf("Task 2 has pid %d\n", pid2);
92 pidx = wait(&status);
93 std::printf("First signal was from task %d\n", pidx);
94 if (!WIFEXITED(status))
95 { std::printf("Task did not exit cleanly\n");
96 kill(pid1, SIGKILL);
97 kill(pid2, SIGKILL);
98 waitpid(pid1, &status, 0);
99 waitpid(pid2, &status, 0);
100 std::printf("Both tasks now dead\n");
101 }
102 pidy = pidx == pid1 ? pid2 : pid1;
103 kill(pidy, SIGKILL);
104 waitpid(pidy, &status, 0);
105 std::printf("Other task (%d) now dead\n", pidy);
106 }
107 }
108 std::printf("All done\n");
109 return 0;
110 }
111