--- l2_ch_pipe.c 2001/09/14 11:13:32 1.9
+++ l2_ch_pipe.c 2001/09/14 15:40:04 1.10
@@ -30,12 +30,29 @@
#include "l2.h"
#include <unistd.h>
+#include <signal.h>
/* declare private channel configuration */
typedef struct {
int iPipe; /* pipe filedescriptor used for writing only */
} l2_ch_pipe_t;
+static void catchsignal(int sig, ...)
+{
+ va_list ap;
+ static l2_context_t *ctx = NULL;
+
+ va_start(ap, sig);
+ if (sig == 0)
+ ctx = va_arg(ap, l2_context_t *);
+ else if (sig == SIGCHLD) {
+ ((l2_ch_pipe_t *)(int *)ctx->vp)->iPipe = -1; /* TODO: Fill in with new pipe fd */
+ }
+ else if (sig == SIGPIPE)
+ ((l2_ch_pipe_t *)(int *)ctx->vp)->iPipe = -1;
+ va_end(ap);
+}
+
/* create channel */
static l2_result_t hook_create(l2_context_t *ctx, l2_channel_t *ch)
{
@@ -70,6 +87,10 @@
if (cfg->iPipe == -1)
return L2_ERR_ARG;
+ catchsignal(0, ctx); /* initialize signal handler with incoming context */
+ signal(SIGCHLD, (void(*)())catchsignal); /* pipe changes descriptor */
+ signal(SIGPIPE, (void(*)())catchsignal); /* pipe closes reading fd */
+
return rv;
}
@@ -78,11 +99,21 @@
l2_level_t level, const char *buf, size_t buf_size)
{
l2_ch_pipe_t *cfg = (l2_ch_pipe_t *)ctx->vp;
+ l2_channel_t *downstream = l2_channel_downstream(ch);
+ l2_result_t rv;
+ /* validate the pipe fd */
+ if (cfg->iPipe == -1)
+ return L2_ERR_ARG;
+
/* write message to channel pipe */
if (write(cfg->iPipe, buf, buf_size) == -1)
return L2_ERR_SYS;
+ /* write to downstream channel */
+ if ((rv = l2_channel_write(downstream, level, buf, buf_size)) != L2_OK)
+ return rv;
+
return L2_OK;
}
@@ -90,11 +121,17 @@
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;
-
+ l2_channel_t *downstream = l2_channel_downstream(ch);
+ l2_result_t rv;
+
/* close channel pipe */
close(cfg->iPipe);
cfg->iPipe = -1;
+ /* close downstream channel, too */
+ if ((rv = l2_channel_close(downstream)) != L2_OK)
+ return rv;
+
return L2_OK;
}
@@ -102,16 +139,22 @@
static l2_result_t hook_destroy(l2_context_t *ctx, l2_channel_t *ch)
{
l2_ch_pipe_t *cfg = (l2_ch_pipe_t *)ctx->vp;
+ l2_channel_t *downstream = l2_channel_downstream(ch);
+ l2_result_t rv;
/* destroy channel configuration */
free(cfg);
+ /* destroy downstream channel, too */
+ if ((rv = l2_channel_destroy(downstream)) != L2_OK)
+ return rv;
+
return L2_OK;
}
/* exported channel handler structure */
l2_handler_t l2_handler_pipe = {
- L2_CHANNEL_OUTPUT,
+ L2_CHANNEL_FILTER,
hook_create,
hook_configure,
NULL,
|