diff --git a/Makefile b/Makefile index e12ddf1..31bc946 100644 --- a/Makefile +++ b/Makefile @@ -72,9 +72,9 @@ vectors.S : vectors.pl ULIB = ulib.o usys.o printf.o umalloc.o -usertests : usertests.o $(ULIB) - $(LD) -N -e main -Ttext 0 -o usertests usertests.o $(ULIB) - $(OBJDUMP) -S usertests > usertests.asm +_usertests : usertests.o $(ULIB) + $(LD) -N -e main -Ttext 0 -o _usertests usertests.o $(ULIB) + $(OBJDUMP) -S _usertests > usertests.asm _echo : echo.o $(ULIB) $(LD) -N -e main -Ttext 0 -o _echo echo.o $(ULIB) @@ -117,10 +117,16 @@ _zombie: zombie.o $(ULIB) $(LD) -N -e main -Ttext 0 -o _zombie zombie.o $(ULIB) $(OBJDUMP) -S _zombie > zombie.asm +_forktest: forktest.o $(ULIB) + # forktest has less library code linked in - needs to be small + # in order to be able to max out the proc table. + $(LD) -N -e main -Ttext 0 -o _forktest forktest.o ulib.o usys.o + $(OBJDUMP) -S _forktest > forktest.asm + mkfs : mkfs.c fs.h cc -o mkfs mkfs.c -UPROGS=usertests _echo _cat _init _kill _ln _ls _mkdir _rm _sh _zombie +UPROGS=_usertests _echo _cat _init _kill _ln _ls _mkdir _rm _sh _zombie _forktest fs.img : mkfs README $(UPROGS) ./mkfs fs.img README $(UPROGS) diff --git a/forktest.c b/forktest.c new file mode 100644 index 0000000..90cc38c --- /dev/null +++ b/forktest.c @@ -0,0 +1,54 @@ +// Test that fork fails gracefully. +// Tiny executable so that the limit can be filling the proc table. + +#include "types.h" +#include "stat.h" +#include "user.h" + +void +printf(int fd, char *s, ...) +{ + write(fd, s, strlen(s)); +} + +void +forktest(void) +{ + int n, pid; + + printf(1, "fork test\n"); + + for(n=0; n<1000; n++){ + pid = fork(); + if(pid < 0) + break; + if(pid == 0) + exit(); + } + + if(n == 1000){ + printf(1, "fork claimed to work 1000 times!\n"); + exit(); + } + + for(; n > 0; n--){ + if(wait() < 0){ + printf(1, "wait stopped early\n"); + exit(); + } + } + + if(wait() != -1){ + printf(1, "wait got too many\n"); + exit(); + } + + printf(1, "fork test OK\n"); +} + +int +main(void) +{ + forktest(); + exit(); +} diff --git a/usertests.c b/usertests.c index 3a9cd9a..17c7044 100644 --- a/usertests.c +++ b/usertests.c @@ -1189,6 +1189,44 @@ iref(void) printf(1, "empty file name OK\n"); } +// test that fork fails gracefully +// the forktest binary also does this, but it runs out of proc entries first. +// inside the bigger usertests binary, we run out of memory first. +void +forktest(void) +{ + int n, pid; + + printf(1, "fork test\n"); + + for(n=0; n<1000; n++){ + pid = fork(); + if(pid < 0) + break; + if(pid == 0) + exit(); + } + + if(n == 1000){ + printf(1, "fork claimed to work 1000 times!\n"); + exit(); + } + + for(; n > 0; n--){ + if(wait() < 0){ + printf(1, "wait stopped early\n"); + exit(); + } + } + + if(wait() != -1){ + printf(1, "wait got too many\n"); + exit(); + } + + printf(1, "fork test OK\n"); +} + int main(int argc, char *argv[]) { @@ -1223,6 +1261,7 @@ main(int argc, char *argv[]) sharedfd(); dirfile(); iref(); + forktest(); exectest();