summaryrefslogtreecommitdiff
path: root/user/usertests.c
diff options
context:
space:
mode:
Diffstat (limited to 'user/usertests.c')
-rw-r--r--user/usertests.c113
1 files changed, 111 insertions, 2 deletions
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();