From: Alan Cox Date: Sat, 3 Jun 2017 23:02:46 +0000 (+0100) Subject: execve: stop blocking in close_on_exec X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=467fbe2b4a204f7ed99382b36605ef0eb309051f;p=FUZIX.git execve: stop blocking in close_on_exec We don't allow closing of a dying process to block so in fact it's really the same issue in the execve case. Dump all the ugly semaphore stuff for a sanity check so we catch any offenders remaining after net was fixed --- diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index e0002a5c..d967f38f 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -300,6 +300,7 @@ struct mount { #define P_STOPPED 4 /* Sleeping, don't wake up for signal */ #define P_FORKING 5 /* In process of forking; do not mess with */ #define P_ZOMBIE 6 /* Exited. */ +#define P_NOSLEEP 7 /* In an internal state where sleep is forbidden */ /* 0 is used to mean 'check we could signal this process' */ diff --git a/Kernel/process.c b/Kernel/process.c index 3b103204..58a487e9 100644 --- a/Kernel/process.c +++ b/Kernel/process.c @@ -16,13 +16,13 @@ * event equal to the process's own ptab address is a wait(). */ + void psleep(void *event) { irqflags_t irq = di(); #ifdef DEBUG kprintf("psleep(0x%p)", event); #endif - switch (udata.u_ptab->p_status) { case P_SLEEP: // echo output from devtty happens while processes are still sleeping but in-context case P_STOPPED: // coming to a halt diff --git a/Kernel/syscall_exec16.c b/Kernel/syscall_exec16.c index bdc4456a..46f7a296 100644 --- a/Kernel/syscall_exec16.c +++ b/Kernel/syscall_exec16.c @@ -86,8 +86,6 @@ static int header_ok(uint8_t *pp) return 1; } -static uint8_t in_execve; - arg_t _execve(void) { staticfast inoptr ino; @@ -158,13 +156,7 @@ arg_t _execve(void) goto nogood2; } - /* We can't allow multiple execs to occur beyond this point at once - otherwise we may deadlock out of buffers. As we already assume - synchronous block I/O on 8bit boxes this isn't really a hit at all */ - while(in_execve) - psleep(&in_execve); - in_execve = 1; - + udata.u_ptab->p_status = P_NOSLEEP; /* Gather the arguments, and put them in temporary buffers. */ abuf = (struct s_argblk *) tmpbuf(); /* Put environment in another buffer. */ @@ -262,19 +254,17 @@ arg_t _execve(void) udata.u_isp = nenvp - 2; // Start execution (never returns) - in_execve = 0; - wakeup(&in_execve); + udata.u_ptab->p_status = P_RUNNING; doexec(progload); // tidy up in various failure modes: nogood3: + udata.u_ptab->p_status = P_RUNNING; brelse(abuf); brelse(ebuf); - in_execve = 0; - wakeup(&in_execve); - nogood2: +nogood2: brelse(buf); - nogood: +nogood: i_deref(ino); return (-1); }