summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--user/cow.c2
-rw-r--r--user/init.c5
-rw-r--r--user/usertests.c113
3 files changed, 115 insertions, 5 deletions
diff --git a/user/cow.c b/user/cow.c
index 45efc98..0426600 100644
--- a/user/cow.c
+++ b/user/cow.c
@@ -129,7 +129,7 @@ filetest()
{
int parent = getpid();
- printf(1, "file test: ");
+ printf(1, "file: ");
buf[0] = 99;
diff --git a/user/init.c b/user/init.c
index f36ba31..03e60da 100644
--- a/user/init.c
+++ b/user/init.c
@@ -31,7 +31,8 @@ main(void)
printf(1, "init: exec sh failed\n");
exit();
}
- while((wpid=wait()) >= 0 && wpid != pid)
- printf(1, "zombie!\n");
+ while((wpid=wait()) >= 0 && wpid != pid){
+ //printf(1, "zombie!\n");
+ }
}
}
diff --git a/user/usertests.c b/user/usertests.c
index ef70bfb..9d46b1a 100644
--- a/user/usertests.c
+++ b/user/usertests.c
@@ -417,16 +417,18 @@ exitwait(void)
{
int i, pid;
+ printf(1, "exitwait test\n");
+
for(i = 0; i < 100; i++){
pid = fork();
if(pid < 0){
printf(1, "fork failed\n");
- return;
+ exit();
}
if(pid){
if(wait() != pid){
printf(1, "wait wrong pid\n");
- return;
+ exit();
}
} else {
exit();
@@ -435,6 +437,109 @@ exitwait(void)
printf(1, "exitwait ok\n");
}
+// try to find races in the reparenting
+// code that handles a parent exiting
+// when it still has live children.
+void
+reparent(void)
+{
+ int master_pid = getpid();
+
+ printf(1, "reparent test\n");
+
+ for(int i = 0; i < 100; i++){
+ int pid = fork();
+ if(pid < 0){
+ printf(1, "fork failed\n");
+ exit();
+ }
+ if(pid){
+ if(wait() != pid){
+ printf(1, "wait wrong pid\n");
+ exit();
+ }
+ } else {
+ int pid2 = fork();
+ if(pid2 < 0){
+ printf(1, "fork failed\n");
+ kill(master_pid);
+ exit();
+ }
+ if(pid2 == 0){
+ exit();
+ } else {
+ exit();
+ }
+ }
+ }
+ printf(1, "reparent ok\n");
+}
+
+// what if two children exit() at the same time?
+void
+twochildren(void)
+{
+ printf(1, "twochildren test\n");
+
+ for(int i = 0; i < 1000; i++){
+ int pid1 = fork();
+ if(pid1 < 0){
+ printf(1, "fork failed\n");
+ exit();
+ }
+ if(pid1 == 0){
+ exit();
+ } else {
+ int pid2 = fork();
+ if(pid2 < 0){
+ printf(1, "fork failed\n");
+ exit();
+ }
+ if(pid2 == 0){
+ exit();
+ } else {
+ wait();
+ wait();
+ }
+ }
+ }
+ printf(1, "twochildren ok\n");
+}
+
+void
+forkforkfork(void)
+{
+ printf(1, "forkforkfork test\n");
+
+ unlink("stopforking");
+
+ int pid = fork();
+ if(pid < 0){
+ printf(1, "fork failed");
+ exit();
+ }
+ if(pid == 0){
+ while(1){
+ int fd = open("stopforking", 0);
+ if(fd >= 0){
+ exit();
+ }
+ if(fork() < 0){
+ close(open("stopforking", O_CREATE|O_RDWR));
+ }
+ }
+
+ exit();
+ }
+
+ sleep(2);
+ close(open("stopforking", O_CREATE|O_RDWR));
+ wait();
+ sleep(1);
+
+ printf(1, "forkforkfork ok\n");
+}
+
void
mem(void)
{
@@ -1751,6 +1856,10 @@ main(int argc, char *argv[])
}
close(open("usertests.ran", O_CREATE));
+ reparent();
+ twochildren();
+ forkforkfork();
+
argptest();
createdelete();
linkunlink();