summaryrefslogtreecommitdiff
path: root/sys/src/9/port/sysproc.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-05-28 23:41:54 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2013-05-28 23:41:54 +0200
commit8cce104fcb63352a6c297f9d2b48f702d46f3412 (patch)
tree5b411f53b40b54fab79bc3400ef9aeda7212326e /sys/src/9/port/sysproc.c
parent6025ad06da148fa368f927c382281a3402a2dc0f (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.c16
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
*/