execve: stop blocking in close_on_exec
authorAlan Cox <alan@linux.intel.com>
Sat, 3 Jun 2017 23:02:46 +0000 (00:02 +0100)
committerAlan Cox <alan@linux.intel.com>
Sat, 3 Jun 2017 23:02:46 +0000 (00:02 +0100)
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

Kernel/include/kernel.h
Kernel/process.c
Kernel/syscall_exec16.c

index e0002a5..d967f38 100644 (file)
@@ -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' */
index 3b10320..58a487e 100644 (file)
  * 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
index bdc4456..46f7a29 100644 (file)
@@ -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);
 }