diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-05-28 23:41:54 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-05-28 23:41:54 +0200 |
commit | 8cce104fcb63352a6c297f9d2b48f702d46f3412 (patch) | |
tree | 5b411f53b40b54fab79bc3400ef9aeda7212326e /sys/src/9/port/sysproc.c | |
parent | 6025ad06da148fa368f927c382281a3402a2dc0f (diff) |
kernel: sysrfork abortion
when we fail to fork resources for the child due to resource
exhaustion, make the half forked child process call pexit()
to free the resources that where allocated and error out.
Diffstat (limited to 'sys/src/9/port/sysproc.c')
-rw-r--r-- | sys/src/9/port/sysproc.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/sys/src/9/port/sysproc.c b/sys/src/9/port/sysproc.c index 0d0e22661..477d50fd5 100644 --- a/sys/src/9/port/sysproc.c +++ b/sys/src/9/port/sysproc.c @@ -21,6 +21,12 @@ sysr1(ulong*) return 0; } +static void +abortion(void*) +{ + pexit("fork aborted", 1); +} + long sysrfork(ulong *arg) { @@ -101,6 +107,14 @@ sysrfork(ulong *arg) p->ureg = up->ureg; p->dbgreg = 0; + /* Abort the child process on error */ + if(waserror()){ + p->kp = 1; + kprocchild(p, abortion, 0); + ready(p); + nexterror(); + } + /* Make a new set of memory segments */ n = flag & RFMEM; qlock(&p->seglock); @@ -164,6 +178,8 @@ sysrfork(ulong *arg) if(up->procctl == Proc_tracesyscall) p->procctl = Proc_tracesyscall; + poperror(); /* abortion */ + /* Craft a return frame which will cause the child to pop out of * the scheduler in user mode with the return register zero */ |