Skip to content

Commit 6919a43

Browse files
author
Margo
committed
Add in-class code for 11/8
1 parent cfd5d34 commit 6919a43

9 files changed

+309
-0
lines changed

shell2/GNUmakefile

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
ALLPROG=parent child waiting-parent noisy-parent badchild waiting-parent2 waiting-parent3 util
2+
all: $(ALLPROG)
3+
O ?= -O2
4+
5+
include ../common/rules.mk
6+
7+
%: %.o $(BUILDSTAMP)
8+
$(CC) $(LDFLAGS) -o $@ $<
9+
10+
%.o: %.c $(BUILDSTAMP)
11+
$(CC) $(CPPFLAGS) $(CFLAGS) $(DEPCFLAGS) $(O) -o $@ -c $<
12+
13+
clean:
14+
rm -f $(ALLPROG) *.o
15+
rm -rf $(DEPSDIR) *.dSYM
16+
17+
.PHONY: all clean

shell2/badchild.c

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <sys/types.h>
2+
#include <errno.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include <unistd.h>
7+
8+
// Sample program that we will exec from parent; just print out its argv.
9+
// And then, bad child that it is, it will loop forever!
10+
int main(int argc, char *argv[]) {
11+
pid_t mypid = getpid();
12+
13+
printf("Hello from process %d\n", mypid);
14+
printf("My argument list is: ");
15+
for (int i = 0; i < argc; i++)
16+
printf("%s ", argv[i]);
17+
printf("\n");
18+
while (1) {
19+
printf("Child looping\n");
20+
sleep(1);
21+
}
22+
}

shell2/child.c

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <sys/types.h>
2+
#include <errno.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include <unistd.h>
7+
8+
// Sample program that we will exec from parent; just print out its argv.
9+
//
10+
int main(int argc, char *argv[]) {
11+
pid_t mypid = getpid();
12+
13+
printf("Hello from process %d\n", mypid);
14+
printf("My argument list is: ");
15+
for (int i = 0; i < argc; i++)
16+
printf("%s ", argv[i]);
17+
printf("\n");
18+
exit(42);
19+
}

shell2/noisy-parent.c

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include <sys/types.h>
2+
#include <errno.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include <unistd.h>
7+
8+
// Sample program that will take another program on the command line
9+
// and call execvp on it.
10+
// So, argv[0] = this process's name
11+
// argv[1] = the program we want to exec
12+
// argv[2-end] = the arguments to the program we want to exec
13+
//
14+
int main(int argc, char *argv[]) {
15+
(void)argc;
16+
17+
pid_t parent_pid = getpid();
18+
19+
printf("Hello from parent pid %d\n", parent_pid);
20+
21+
pid_t child = fork();
22+
23+
if (child == 0) {
24+
printf("Hi! I'm the child pid %d\n", getpid());
25+
26+
if (execvp(argv[1], argv+1) == -1) {
27+
printf("The exec failed: %s\n", strerror(errno));
28+
exit(1);
29+
}
30+
31+
printf("The exec succeeded! Here is pid %d\n", getpid());
32+
} else if (child > 0) {
33+
printf("Hi! I'm the parent pid %d\n", getpid());
34+
} else {
35+
printf("Fork failed!\n");
36+
}
37+
38+
// Annoying parent is going to clutter up the console
39+
for (int i = 0; i < 100; i++)
40+
printf("Yak yak yak\n");
41+
}

shell2/parent.c

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <sys/types.h>
2+
#include <errno.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include <unistd.h>
7+
8+
// Sample program that will take another program on the command line
9+
// and call execvp on it.
10+
// So, argv[0] = this process's name
11+
// argv[1] = the program we want to exec
12+
// argv[2-end] = the arguments to the program we want to exec
13+
//
14+
int main(int argc, char *argv[]) {
15+
(void)argc;
16+
17+
pid_t parent_pid = getpid();
18+
19+
printf("Hello from parent pid %d\n", parent_pid);
20+
21+
pid_t child = fork();
22+
23+
if (child == 0) {
24+
printf("Hi! I'm the child pid %d\n", getpid());
25+
26+
if (execvp(argv[1], argv+1) == -1) {
27+
printf("The exec failed: %s\n", strerror(errno));
28+
exit(1);
29+
}
30+
31+
printf("The exec succeeded! Here is pid %d\n", getpid());
32+
} else if (child > 0) {
33+
printf("Hi! I'm the parent pid %d\n", getpid());
34+
} else {
35+
printf("Fork failed!\n");
36+
}
37+
}

shell2/util.c

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <sys/types.h>
2+
#include <sys/stat.h>
3+
#include <assert.h>
4+
#include <fcntl.h>
5+
#include <unistd.h>
6+
int
7+
main(void)
8+
{
9+
char c;
10+
int fd, n = 0;
11+
12+
assert((fd = open("/dev/null", O_RDONLY)) > 0);
13+
while (1)
14+
n += read(fd, &c, 1);
15+
return (0);
16+
}

shell2/waiting-parent.c

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include <sys/types.h>
2+
#include <sys/wait.h>
3+
#include <errno.h>
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <string.h>
7+
#include <unistd.h>
8+
9+
// Sample program that will take another program on the command line
10+
// and call execvp on it.
11+
// So, argv[0] = this process's name
12+
// argv[1] = the program we want to exec
13+
// argv[2-end] = the arguments to the program we want to exec
14+
//
15+
int main(int argc, char *argv[]) {
16+
(void)argc;
17+
18+
pid_t parent_pid = getpid();
19+
20+
printf("Hello from parent pid %d\n", parent_pid);
21+
22+
pid_t child = fork();
23+
24+
if (child == 0) {
25+
printf("Hi! I'm the child pid %d\n", getpid());
26+
27+
if (execvp(argv[1], argv+1) == -1) {
28+
printf("The exec failed: %s\n", strerror(errno));
29+
exit(1);
30+
}
31+
32+
printf("The exec succeeded! Here is pid %d\n", getpid());
33+
} else if (child > 0) {
34+
printf("Hi! I'm the parent pid %d\n", getpid());
35+
} else {
36+
printf("Fork failed!\n");
37+
}
38+
39+
// Wait for the child to exit
40+
int exit_status;
41+
pid_t exit_pid = waitpid(child, &exit_status, 0);
42+
printf("Child %d exited with status: %d\n",
43+
exit_pid, WEXITSTATUS(exit_status));
44+
}

shell2/waiting-parent2.c

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include <sys/types.h>
2+
#include <sys/wait.h>
3+
#include <errno.h>
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <string.h>
7+
#include <unistd.h>
8+
9+
// Sample program that will take another program on the command line
10+
// and call execvp on it.
11+
// So, argv[0] = this process's name
12+
// argv[1] = the program we want to exec
13+
// argv[2-end] = the arguments to the program we want to exec
14+
//
15+
int main(int argc, char *argv[]) {
16+
(void)argc;
17+
18+
pid_t parent_pid = getpid();
19+
20+
printf("Hello from parent pid %d\n", parent_pid);
21+
22+
pid_t child = fork();
23+
24+
if (child == 0) {
25+
printf("Hi! I'm the child pid %d\n", getpid());
26+
27+
if (execvp(argv[1], argv+1) == -1) {
28+
printf("The exec failed: %s\n", strerror(errno));
29+
exit(1);
30+
}
31+
32+
printf("The exec succeeded! Here is pid %d\n", getpid());
33+
} else if (child > 0) {
34+
printf("Hi! I'm the parent pid %d\n", getpid());
35+
} else {
36+
printf("Fork failed!\n");
37+
}
38+
39+
// Wait for the child to exit
40+
int exit_status;
41+
pid_t exit_pid;
42+
while (1) {
43+
exit_pid = waitpid(child, &exit_status, WNOHANG);
44+
if (exit_pid == 0)
45+
printf("Child is running with no state change\n");
46+
else if (WIFEXITED(exit_status)) {
47+
break;
48+
}
49+
// If we got here, we still have a child - sleep a bit and
50+
// wait.
51+
sleep(1);
52+
}
53+
printf("Child %d exited with status: %d\n",
54+
exit_pid, WEXITSTATUS(exit_status));
55+
}

shell2/waiting-parent3.c

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <sys/types.h>
2+
#include <sys/wait.h>
3+
#include <errno.h>
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <string.h>
7+
#include <unistd.h>
8+
9+
// Sample program that will take another program on the command line
10+
// and call execvp on it.
11+
// So, argv[0] = this process's name
12+
// argv[1] = the program we want to exec
13+
// argv[2-end] = the arguments to the program we want to exec
14+
//
15+
int main(int argc, char *argv[]) {
16+
(void)argc;
17+
18+
pid_t parent_pid = getpid();
19+
20+
printf("Hello from parent pid %d\n", parent_pid);
21+
22+
pid_t child = fork();
23+
24+
if (child == 0) {
25+
printf("Hi! I'm the child pid %d\n", getpid());
26+
27+
if (execvp(argv[1], argv+1) == -1) {
28+
printf("The exec failed: %s\n", strerror(errno));
29+
exit(1);
30+
}
31+
32+
printf("The exec succeeded! Here is pid %d\n", getpid());
33+
} else if (child > 0) {
34+
printf("Hi! I'm the parent pid %d\n", getpid());
35+
} else {
36+
printf("Fork failed!\n");
37+
}
38+
39+
// Wait for the child to exit
40+
int exit_status;
41+
pid_t exit_pid;
42+
while (1) {
43+
exit_pid = waitpid(child, &exit_status, WUNTRACED | WCONTINUED);
44+
if (WIFEXITED(exit_status))
45+
break;
46+
else if (WIFSIGNALED(exit_status)) {
47+
printf("Child received a signal\n");
48+
break;
49+
} else if (WIFSTOPPED(exit_status)) {
50+
printf("Child process is stopped; keep waiting\n");
51+
}
52+
// If we got here, we still have a child - sleep a bit and
53+
// wait.
54+
sleep(1);
55+
}
56+
printf("Child %d exited with status: %d\n",
57+
exit_pid, WEXITSTATUS(exit_status));
58+
}

0 commit comments

Comments
 (0)