Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rdemeter
GitHub Repository: rdemeter/so
Path: blob/master/lab3/forks.c
221 views
1
#include <stdlib.h>
2
#include <stdio.h>
3
#include <unistd.h>
4
#include <sys/types.h>
5
#include <wait.h>
6
#include <signal.h>
7
8
void fork1()
9
{
10
11
int x = 1;
12
pid_t pid = fork();
13
if (pid == 0) {
14
printf("Child has x = %d\n", ++x);
15
} else {
16
printf("Parent has x = %d\n", --x);
17
}
18
printf("Bye from process %d with x = %d\n", getpid(), x);
19
}
20
21
void fork2()
22
{
23
printf("L0\n");
24
fork();
25
printf("L1\n");
26
fork();
27
printf("Bye\n");
28
}
29
30
void fork3()
31
{
32
printf("L0\n");
33
fork();
34
printf("L1\n");
35
fork();
36
printf("L2\n");
37
fork();
38
printf("Bye\n");
39
}
40
41
void fork4()
42
{
43
printf("L0\n");
44
if (fork() != 0) {
45
printf("L1\n");
46
if (fork() != 0) {
47
printf("L2\n");
48
fork();
49
}
50
}
51
printf("Bye\n");
52
}
53
54
void fork5()
55
{
56
printf("L0\n");
57
if (fork() == 0) {
58
printf("L1\n");
59
if (fork() == 0) {
60
printf("L2\n");
61
fork();
62
}
63
}
64
printf("Bye\n");
65
}
66
67
void cleanup(void) {
68
printf("Cleaning up\n");
69
}
70
71
void fork6()
72
{
73
atexit(cleanup);
74
fork();
75
exit(0);
76
}
77
78
/* Demonstration of zombies.
79
Run in background and then perform ps */
80
void fork7()
81
{
82
if (fork() == 0) {
83
/* Child */
84
printf("Terminating Child, PID = %d\n", getpid());
85
exit(0);
86
} else {
87
printf("Running Parent, PID = %d\n", getpid());
88
while (1)
89
; /* Infinite loop */
90
}
91
}
92
93
/* Demonstration of nonterminating child. Must kill */
94
void fork8()
95
{
96
if (fork() == 0) {
97
/* Child */
98
printf("Running Child, PID = %d\n",
99
getpid());
100
while (1)
101
; /* Infinite loop */
102
} else {
103
printf("Terminating Parent, PID = %d\n",
104
getpid());
105
exit(0);
106
}
107
}
108
109
void fork9()
110
{
111
int child_status;
112
113
if (fork() == 0) {
114
printf("HC: hello from child\n");
115
} else {
116
printf("HP: hello from parent\n");
117
wait(&child_status);
118
printf("CT: child has terminated\n");
119
}
120
printf("Bye\n");
121
}
122
123
#define N 5
124
void fork10()
125
{
126
pid_t pid[N];
127
int i;
128
int child_status;
129
for (i = 0; i < N; i++)
130
if ((pid[i] = fork()) == 0)
131
exit(100+i); /* Child */
132
for (i = 0; i < N; i++) {
133
pid_t wpid = wait(&child_status);
134
if (WIFEXITED(child_status))
135
printf("Child %d terminated with exit status %d\n",
136
wpid, WEXITSTATUS(child_status));
137
else
138
printf("Child %d terminate abnormally\n", wpid);
139
}
140
}
141
142
void fork11()
143
{
144
pid_t pid[N];
145
int i;
146
int child_status;
147
for (i = 0; i < N; i++)
148
if ((pid[i] = fork()) == 0)
149
exit(100+i); /* Child */
150
for (i = 0; i < N; i++) {
151
pid_t wpid = waitpid(pid[i], &child_status, 0);
152
if (WIFEXITED(child_status))
153
printf("Child %d terminated with exit status %d\n",
154
wpid, WEXITSTATUS(child_status));
155
else
156
printf("Child %d terminate abnormally\n", wpid);
157
}
158
}
159
160
void fork12()
161
{
162
pid_t pid[N];
163
int i;
164
int child_status;
165
for (i = 0; i < N; i++)
166
if ((pid[i] = fork()) == 0) {
167
/* Child: Infinite Loop */
168
while(1)
169
;
170
}
171
for (i = 0; i < N; i++) {
172
printf("Killing process %d\n", pid[i]);
173
kill(pid[i], SIGINT);
174
}
175
for (i = 0; i < N; i++) {
176
pid_t wpid = wait(&child_status);
177
if (WIFEXITED(child_status))
178
printf("Child %d terminated with exit status %d\n",
179
wpid, WEXITSTATUS(child_status));
180
else
181
printf("Child %d terminated abnormally\n", wpid);
182
}
183
}
184
185
void int_handler(int sig)
186
{
187
printf("Process %d received signal %d\n", getpid(), sig);
188
exit(0);
189
}
190
191
void fork13()
192
{
193
pid_t pid[N];
194
int i;
195
int child_status;
196
signal(SIGINT, int_handler);
197
for (i = 0; i < N; i++)
198
if ((pid[i] = fork()) == 0) {
199
/* Child: Infinite Loop */
200
while(1)
201
;
202
}
203
for (i = 0; i < N; i++) {
204
printf("Killing process %d\n", pid[i]);
205
kill(pid[i], SIGINT);
206
}
207
for (i = 0; i < N; i++) {
208
pid_t wpid = wait(&child_status);
209
if (WIFEXITED(child_status))
210
printf("Child %d terminated with exit status %d\n",
211
wpid, WEXITSTATUS(child_status));
212
else
213
printf("Child %d terminated abnormally\n", wpid);
214
}
215
}
216
217
int ccount = 0;
218
void child_handler(int sig)
219
{
220
int child_status;
221
pid_t pid = wait(&child_status);
222
ccount--;
223
printf("Received signal %d from process %d\n", sig, pid);
224
}
225
226
void fork14()
227
{
228
pid_t pid[N];
229
int i;
230
int child_status;
231
ccount = N;
232
signal(SIGCHLD, child_handler);
233
for (i = 0; i < N; i++)
234
if ((pid[i] = fork()) == 0) {
235
/* Child: Exit */
236
exit(0);
237
}
238
while (ccount > 0)
239
pause();
240
}
241
242
void child_handler2(int sig)
243
{
244
int child_status;
245
pid_t pid;
246
while ((pid = wait(&child_status)) > 0) {
247
ccount--;
248
printf("Received signal %d from process %d\n", sig, pid);
249
}
250
}
251
252
void fork15()
253
{
254
pid_t pid[N];
255
int i;
256
int child_status;
257
ccount = N;
258
259
signal(SIGCHLD, child_handler2);
260
for (i = 0; i < N; i++)
261
if ((pid[i] = fork()) == 0) {
262
/* Child: Exit */
263
exit(0);
264
}
265
while (ccount > 0) {
266
pause();
267
}
268
}
269
270
271
int main(int argc, char *argv[])
272
{
273
int option = 0;
274
if (argc > 1)
275
option = atoi(argv[1]);
276
switch(option) {
277
case 1: fork1();
278
break;
279
case 2: fork2();
280
break;
281
case 3: fork3();
282
break;
283
case 4: fork4();
284
break;
285
case 5: fork5();
286
break;
287
case 6: fork6();
288
break;
289
case 7: fork7();
290
break;
291
case 8: fork8();
292
break;
293
case 9: fork9();
294
break;
295
case 10: fork10();
296
break;
297
case 11: fork11();
298
break;
299
case 12: fork12();
300
break;
301
case 13: fork13();
302
break;
303
case 14: fork14();
304
break;
305
case 15: fork15();
306
break;
307
default:
308
printf("Unknown option %d\n", option);
309
break;
310
}
311
return 0;
312
}
313
314