OSSP CVS Repository

ossp - Check-in [1068]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 1068
Date: 2001-Oct-04 14:34:41 (local)
2001-Oct-04 12:34:41 (UTC)
User:ms
Branch:
Comment: Bug fixes and new child process blocking with oneshot mode.
Tickets:
Inspections:
Files:
ossp-pkg/l2/l2_ch_pipe.c      1.23 -> 1.24     33 inserted, 29 deleted

ossp-pkg/l2/l2_ch_pipe.c 1.23 -> 1.24

--- l2_ch_pipe.c 2001/10/02 15:51:32     1.23
+++ l2_ch_pipe.c 2001/10/04 12:34:41     1.24
@@ -62,7 +62,7 @@
 
     if (sig == SIGCHLD) {
         TRACE("SIGCHLD caught");
-        Pid = waitpid(-1, &iStatus, WUNTRACED);
+        Pid = waitpid(-1, &iStatus, WUNTRACED | WNOHANG);
         if (WIFEXITED(iStatus))
             TRACE("EXITED child");     /* child finished and returned       */
         else if (WIFSIGNALED(iStatus))
@@ -314,28 +314,27 @@
     if (sigaction(SIGPIPE, &locact, &cfg->sigpipe) < 0)
         return L2_ERR_SYS;
 
-    if (pipe(cfg->piFd) == -1)                /* open the pipe            */
+    if (pipe(cfg->piFd) == -1) /* open the pipe */
         return L2_ERR_SYS;
 
     /* short circuit hack, if in oneshot mode and not yet opened then return */
     if ((cfg->iRtme == L2_PIPE_RUNTIME_ONESHOT) && (ch->state != L2_CHSTATE_OPENED))
         return L2_OK;
     else
-        spawn_command(cfg); /* spawn the command process */
-
-    return L2_OK;
+        return spawn_command(cfg); /* spawn the command process */
 }
 
 /* write to channel, possibly recursively */
 static l2_result_t hook_write(l2_context_t *ctx, l2_channel_t *ch,
                               l2_level_t level, const char *buf, size_t buf_size)
 {
-    l2_ch_pipe_t *cfg = (l2_ch_pipe_t *)ctx->vp;
-    l2_result_t rv;
+    l2_result_t   rv      = L2_OK;
+    l2_ch_pipe_t *cfg     = (l2_ch_pipe_t *)ctx->vp;
 
-    /* we must still spawn the child command process if we are in oneshot mode */
-    if ((cfg->iRtme == L2_PIPE_RUNTIME_ONESHOT) && (cfg->Pid != -1))
-        spawn_command(cfg);
+    /* spawn the child command process if we are in oneshot mode */
+    if ((cfg->iRtme == L2_PIPE_RUNTIME_ONESHOT) && (cfg->Pid == -1))
+        if (spawn_command(cfg) != L2_OK)
+            return L2_ERR_SYS; /* immediate return if we can't spawn command */
 
     /* write message to channel pipe */
     if (write(cfg->piFd[1], buf, buf_size) == -1) {
@@ -346,29 +345,26 @@
                 return rv;
             return hook_write(ctx, ch, level, buf, buf_size);
         }
-        else { /* not broken pipe problem or over the fail limit */
-            cfg->iWritefail = 0; /* reset pipe failure counter   */
-            return L2_ERR_SYS;
+        else { /* not broken pipe problem or over the fail limit, so panic */
+            cfg->iWritefail = 0;             /* reset pipe failure counter */
+            rv = L2_ERR_SYS;
         }
     }
-    else {                   /* write() to pipe succeeded  */
+    else                     /* write() to pipe succeeded  */
         cfg->iWritefail = 0; /* reset pipe failure counter */
-        return L2_OK;
-    }
+
+    /* block until child terminates if in oneshot execmode */
+    if ((cfg->iRtme == L2_PIPE_RUNTIME_ONESHOT) && (cfg->Pid != -1))
+        cfg->Pid = waitpid(cfg->Pid, NULL, WUNTRACED | WNOHANG);
+
+    return rv;
 }
 
 /* close channel */
 static l2_result_t hook_close(l2_context_t *ctx, l2_channel_t *ch)
 {
-    l2_ch_pipe_t *cfg = (l2_ch_pipe_t *)ctx->vp;
-
-    /* restore previous signal context, but only if it was saved and replaced */
-    if (&cfg->sigchld.sa_handler) {
-        if (sigaction(SIGCHLD, &cfg->sigchld, 0) < 0)
-            return L2_ERR_SYS;
-        if (sigaction(SIGPIPE, &cfg->sigpipe, 0) < 0)
-            return L2_ERR_SYS;
-    }
+    l2_result_t   rv      = L2_OK;
+    l2_ch_pipe_t *cfg     = (l2_ch_pipe_t *)ctx->vp;
 
     /* close null device */
     if (cfg->iNulldev != -1) {
@@ -382,14 +378,22 @@
         cfg->piFd[1] = -1;
     }
 
-    /* kill child process if already started */
+    /* restore previous signal context, but only if it was saved and replaced */
+    if (&cfg->sigchld.sa_handler) {
+        if (sigaction(SIGCHLD, &cfg->sigchld, 0) < 0)
+            rv = L2_ERR_SYS;
+        if (sigaction(SIGPIPE, &cfg->sigpipe, 0) < 0)
+            rv = L2_ERR_SYS;
+    }
+
+    /* kill child process if still running */
     if (cfg->Pid != -1) {
-        if ((kill (cfg->Pid, SIGTERM)) && (errno != ESRCH))
-            return L2_ERR_SYS;
+        kill(cfg->Pid, SIGTERM);
+        cfg->Pid = waitpid(cfg->Pid, NULL, WUNTRACED | WNOHANG);
         cfg->Pid = -1;
     }
 
-    return L2_OK;
+    return rv;
 }
 
 /* destroy channel */

CVSTrac 2.0.1