--- 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 */
|