Index: ossp-pkg/sio/sio.c RCS File: /v/ossp/cvs/ossp-pkg/sio/sio.c,v rcsdiff -q -kk '-r1.1' '-r1.2' -u '/v/ossp/cvs/ossp-pkg/sio/sio.c,v' 2>/dev/null --- sio.c 2002/10/22 12:57:20 1.1 +++ sio.c 2002/10/23 17:05:10 1.2 @@ -57,19 +57,27 @@ struct sio_halfduplex_st { NODE(sio_halfduplex_t) hd; sio_stage_t *stage; + sio_halfduplex_t *cross; + al_t *al; sio_rc_t (*func)(sio_t *, al_t *, void *); }; struct sio_st { struct { - LIST(sio_halfduplex_t) hd; + LIST(sio_halfduplex_t) hd; al_t *al; } readers; struct { - LIST(sio_halfduplex_t) hd; + LIST(sio_halfduplex_t) hd; al_t *al; } writers; + sio_labelnum_t label_data; + sio_labelnum_t label_error; + sio_labelnum_t label_eof; }; +#define SIO_LABEL_DATA(sio) ((void*)&(sio)->label_data) +#define SIO_LABEL_ERROR(sio) ((void*)&(sio)->label_error) +#define SIO_LABEL_EOF(sio) ((void*)&(sio)->label_eof) struct sio_stage_st { sio_halfduplex_t reader; @@ -82,23 +90,38 @@ /****************************************************************************/ static -sio_rc_t sio_strategy(sio_t *sio, sio_halfduplex_t *chain, al_t *al) +sio_rc_t sio_strategy(sio_t *sio, sio_halfduplex_t *chain) { sio_rc_t rc; sio_halfduplex_t *h; + /* + * call stage and direct data upstream/downstream + * according to response code + * + * if we the stage does not return a direction, + * simply end the code + * + * if we drop off the chain, simply result SIO_OK + * + */ h = chain; while (h != NULL) { - rc = h->func(sio, al, h->stage->userdata); + rc = h->func(sio, h->al, h->stage->userdata); if (rc == SIO_UPSTREAM) h = NEXT(h,hd); else if (rc == SIO_DOWNSTREAM) - h = NEXT(h,hd); + h = PREV(h,hd); + else if (rc == SIO_XSTREAM) + h = h->cross; else break; } - return SIO_OK; + if (h == NULL) + rc = SIO_OK; + + return rc; } /**************************************************************************/ @@ -118,6 +141,10 @@ LISTINIT(&sio->readers,hd); LISTINIT(&sio->writers,hd); + sio->label_data = SIO_LN_DATA; + sio->label_error = SIO_LN_ERROR; + sio->label_eof = SIO_LN_EOF; + *siop = sio; return SIO_OK; @@ -138,7 +165,6 @@ { sio_rc_t rc; sio_stage_t *sios; - void *u; /* argument sanity check(s) */ if (sio == NULL || siom == NULL || siosp == NULL) @@ -151,19 +177,26 @@ NODEINIT(&sios->reader,hd); NODEINIT(&sios->writer,hd); sios->module = siom; - sios->userdata = u; + sios->userdata = NULL; sios->rw = SIO_MODE_INVALID; sios->reader.func = siom->input; sios->reader.stage = sios; sios->writer.func = siom->output; sios->writer.stage = sios; - rc = sios->module->init(sio, sios->userdata); + rc = sios->module->init(sio, &sios->userdata); + if (rc != SIO_OK) { + free(sios); + return SIO_RC(rc); + } + + *siosp = sios; return SIO_RC(rc); } -sio_rc_t sio_cofigure_stage(sio_t *sio, sio_stage_t *sios, void *obj, void *value) +sio_rc_t sio_configure_stage(sio_t *sio, sio_stage_t *sios, + void *obj, void *value) { sio_rc_t rc; @@ -190,39 +223,104 @@ return SIO_OK; } +static +sio_rc_t sio_create_al(sio_t *sio, sio_mode_t rw) +{ + al_rc_t arc; + int freereader = 0; + + if (rw == SIO_MODE_READ || rw == SIO_MODE_READWRITE) { + if (ISEMPTY(&sio->readers,hd)) { + arc = al_create(&sio->readers.al); + if (arc != AL_OK) + return SIO_ERR_INT; + freereader = 1; + } + } + if (rw == SIO_MODE_WRITE || rw == SIO_MODE_READWRITE) { + if (ISEMPTY(&sio->writers,hd)) { + arc = al_create(&sio->writers.al); + if (arc != AL_OK) { + if (freereader) + al_destroy(sio->readers.al); + return SIO_ERR_INT; + } + } + } + + return SIO_OK; +} + +static +sio_rc_t sio_destroy_al(sio_t *sio, sio_mode_t rw) +{ + if (rw == SIO_MODE_READ || rw == SIO_MODE_READWRITE) { + if (ISEMPTY(&sio->readers,hd)) { + al_destroy(sio->readers.al); + sio->readers.al = NULL; + } + } + if (rw == SIO_MODE_WRITE || rw == SIO_MODE_READWRITE) { + if (ISEMPTY(&sio->writers,hd)) { + al_destroy(sio->writers.al); + sio->writers.al = NULL; + } + } + + return SIO_OK; +} + sio_rc_t sio_attach(sio_t *sio, sio_stage_t *sios, sio_mode_t rw) { sio_rc_t rc; + int freereader = 0; /* argument sanity check(s) */ if (sio == NULL || sios == NULL) return SIO_RC(SIO_ERR_ARG); - - /* is module already attached ? */ - if (sios->rw != SIO_MODE_INVALID) - return SIO_RC(SIO_ERR_ARG); - - /* prepare module for being attached */ - rc = sios->module->open(sio, sios->userdata); - if (rc != SIO_OK) return SIO_RC(rc); - switch (rw) { case SIO_MODE_READ: - ADDTAIL(&sio->readers,hd,&sios->reader); - break; case SIO_MODE_WRITE: - ADDTAIL(&sio->writers,hd,&sios->writer); - break; case SIO_MODE_READWRITE: - ADDTAIL(&sio->readers,hd,&sios->reader); - ADDTAIL(&sio->writers,hd,&sios->writer); break; default: return SIO_RC(SIO_ERR_ARG); } - /* Remember the lists that sios has been attached to */ - sios->rw = rw; + /* is module already attached ? */ + if (sios->rw != SIO_MODE_INVALID) + return SIO_RC(SIO_ERR_ARG); + + /* create assembly lines (if aready existing) */ + rc = sio_create_al(sio, rw); + if (rc != SIO_OK) + return SIO_RC(rc); + + if (rw == SIO_MODE_READ || rw == SIO_MODE_READWRITE) { + rc = sios->module->openr(sio, sio->readers.al, sios->userdata); + if (rc != SIO_OK) { + sio_destroy_al(sio, rw); + return SIO_ERR_INT; + } + ADDTAIL(&sio->readers,hd,&sios->reader); + freereader = 1; + } + if (rw == SIO_MODE_WRITE || rw == SIO_MODE_READWRITE) { + rc = sios->module->openw(sio, sio->writers.al, sios->userdata); + if (rc != SIO_OK) { + if (freereader) { + REMOVE(&sio->readers,hd,&sios->reader); + sios->module->closer(sio, sio->readers.al, sios->userdata); + } + sio_destroy_al(sio, rw); + return SIO_ERR_INT; + } + ADDTAIL(&sio->writers,hd,&sios->writer); + } + + sios->reader.al = sio->readers.al; + sios->writer.al = sio->writers.al; + sios->rw = rw; return SIO_OK; } @@ -237,21 +335,33 @@ switch (sios->rw) { case SIO_MODE_READ: - REMOVE(&sio->readers,hd,&sios->reader); - break; case SIO_MODE_WRITE: - REMOVE(&sio->writers,hd,&sios->writer); - break; case SIO_MODE_READWRITE: - REMOVE(&sio->readers,hd,&sios->reader); - REMOVE(&sio->writers,hd,&sios->writer); break; default: return SIO_RC(SIO_ERR_ARG); - break; } - rc = sios->module->close(sio, sios->userdata); + rc = SIO_OK; + if (sios->rw == SIO_MODE_WRITE || sios->rw == SIO_MODE_READWRITE) { + REMOVE(&sio->writers,hd,&sios->writer); + rc = sios->module->closew(sio, sio->writers.al, sios->userdata); + } + if (sios->rw == SIO_MODE_READ || sios->rw == SIO_MODE_READWRITE) { + REMOVE(&sio->readers,hd,&sios->reader); + if (rc == SIO_OK) + rc = sios->module->closer(sio, sio->readers.al, sios->userdata); + else + /* XXX - double error handling ? */ + sios->module->closer(sio, sio->readers.al, sios->userdata); + } + + sios->writer.al = NULL; + sios->reader.al = NULL; + + sio_destroy_al(sio, sios->rw); + + sios->rw = SIO_MODE_INVALID; return SIO_RC(rc); } @@ -259,17 +369,23 @@ sio_rc_t sio_input(sio_t *sio, al_t *al, size_t limit) { sio_rc_t rc; - al_t *src = sio->readers.al; + sio_halfduplex_t *h; + al_t *src; size_t n; /* argument sanity check(s) */ if (sio == NULL || al == NULL) return SIO_RC(SIO_ERR_ARG); + h = HEAD(&sio->readers,hd); + if (h == NULL) + return SIO_RC(SIO_ERR_ARG); + + src = h->al; n = al_bytes(src); if (n == 0) { - rc = sio_strategy(sio, HEAD(&sio->readers,hd), src); + rc = sio_strategy(sio, h); if (rc != SIO_OK) return SIO_RC(rc); n = al_bytes(src); @@ -286,61 +402,55 @@ return SIO_OK; } -sio_rc_t sio_discard(sio_t *sio) -{ - sio_rc_t rc; - al_t *src = sio->readers.al; - size_t n; - - /* argument sanity check(s) */ - if (sio == NULL) - return SIO_RC(SIO_ERR_ARG); - - while ((n = al_bytes(src)) > 0) { - rc = sio_strategy(sio, HEAD(&sio->readers,hd), src); - if (rc != SIO_OK) - break; - } - - if (rc == SIO_ERR_EOF) - return SIO_OK; - - return SIO_RC(rc); -} - sio_rc_t sio_output(sio_t *sio, al_t *al) { sio_rc_t rc; - al_t *dst = sio->writers.al; + al_rc_t arc; + sio_halfduplex_t *h; + al_t *dst; size_t n; /* argument sanity check(s) */ if (sio == NULL || al == NULL) return SIO_RC(SIO_ERR_ARG); + h = HEAD(&sio->writers,hd); + if (h == NULL) + return SIO_RC(SIO_ERR_ARG); + dst = h->al; + n = al_bytes(dst); - al_splice(dst, n, 0, al, NULL); + arc = al_splice(dst, n, 0, al, NULL); + if (arc != AL_OK) + return SIO_RC(SIO_ERR_INT); - rc = sio_strategy(sio, HEAD(&sio->writers,hd), dst); + rc = sio_strategy(sio, h); return SIO_RC(rc); } -sio_rc_t sio_flush(sio_t *sio) +sio_rc_t sio_push(sio_t *sio) { sio_rc_t rc; - al_t *dst = sio->writers.al; - size_t n; + al_rc_t arc; + sio_halfduplex_t *h; + al_t *dst; + char eof = '\0'; /* argument sanity check(s) */ if (sio == NULL) return SIO_RC(SIO_ERR_ARG); - while ((n = al_bytes(dst)) > 0) { - rc = sio_strategy(sio, HEAD(&sio->writers,hd), sio->writers.al); - if (rc != SIO_OK) - break; - } + h = HEAD(&sio->writers,hd); + if (h == NULL) + return SIO_RC(SIO_ERR_ARG); + dst = h->al; + + arc = al_append_bytes(dst, &eof, 1, SIO_LABEL_EOF(sio)); + if (arc != AL_OK) + return SIO_RC(SIO_ERR_INT); + + rc = sio_strategy(sio, h); return SIO_RC(rc); } @@ -351,12 +461,16 @@ sio_rc_t rc; al_t *al; + if (n == 0) + return SIO_OK; + arc = al_create(&al); if (arc != AL_OK) return SIO_RC(SIO_ERR_INT); rc = sio_input(sio, al, n); if (rc == AL_OK) { - arc = al_flatten(al, 0, n, dst, actualp); + arc = al_flatten(al, 0, n, AL_FORWARD_SPAN, SIO_LABEL_DATA(sio), + dst, actualp); if (arc != AL_OK) rc = SIO_ERR_INT; } @@ -373,10 +487,13 @@ sio_rc_t rc; al_t *al; + if (n == 0) + return SIO_OK; + arc = al_create(&al); if (arc != AL_OK) return SIO_RC(SIO_ERR_INT); - arc = al_append_bytes(al, src, n); + arc = al_append_bytes(al, src, n, SIO_LABEL_DATA(sio)); if (arc != AL_OK) rc = SIO_ERR_INT; else @@ -401,9 +518,32 @@ case SIO_ERR_INT: mess = "Internal Error"; break; case SIO_UPSTREAM: mess = "Invoke Upstream Stage"; break; case SIO_DOWNSTREAM: mess = "Invoke Downstream Stage"; break; + case SIO_XSTREAM: mess = "Invoke Crossstream Stage"; break; default: mess = "Invalid Result Code"; break; } return mess; } +sio_rc_t sio_label(sio_t *sio, sio_labelnum_t ln, void **p) +{ + void *label; + + switch (ln) { + case SIO_LN_DATA: + label = SIO_LABEL_DATA(sio); + break; + case SIO_LN_ERROR: + label = SIO_LABEL_ERROR(sio); + break; + case SIO_LN_EOF: + label = SIO_LABEL_EOF(sio); + break; + default: + return SIO_ERR_ARG; + } + + *p = label; + return SIO_OK; +} + Index: ossp-pkg/sio/sio.h RCS File: /v/ossp/cvs/ossp-pkg/sio/sio.h,v rcsdiff -q -kk '-r1.1' '-r1.2' -u '/v/ossp/cvs/ossp-pkg/sio/sio.h,v' 2>/dev/null --- sio.h 2002/10/22 12:57:20 1.1 +++ sio.h 2002/10/23 17:05:10 1.2 @@ -28,6 +28,9 @@ ** sio.h: stream I/O public API definition */ +#ifndef __SIO_H__ +#define __SIO_H__ + typedef enum { SIO_OK, SIO_ERR_ARG, @@ -36,7 +39,8 @@ SIO_ERR_SYS, SIO_ERR_INT, SIO_UPSTREAM, - SIO_DOWNSTREAM + SIO_DOWNSTREAM, + SIO_XSTREAM } sio_rc_t; typedef enum { @@ -71,4 +75,8 @@ sio_rc_t sio_read(sio_t *sio, char *dst, size_t n, size_t *actualp); sio_rc_t sio_write(sio_t *sio, char *src, size_t n, size_t *actualp); +sio_rc_t sio_push(sio_t *sio); + const char *sio_error(sio_rc_t rc); + +#endif /* __SIO_H__ */ Index: ossp-pkg/sio/sio_buffer.c RCS File: /v/ossp/cvs/ossp-pkg/sio/sio_buffer.c,v co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/sio/sio_buffer.c,v' | diff -u /dev/null - -L'ossp-pkg/sio/sio_buffer.c' 2>/dev/null --- ossp-pkg/sio/sio_buffer.c +++ - 2025-10-23 06:07:09.400415863 +0200 @@ -0,0 +1,195 @@ +#include +#include +#include + +#include "al.h" +#include "sio.h" +#include "sio_module.h" + +typedef struct { + size_t outputsize; + al_tx_t *outputtx; + size_t inputsize; + al_t *input, *output; +} private_t; + +/* + * create stage + * + * allocate private instance data + */ +static +sio_rc_t buffer_init(sio_t *sio, void **u) +{ + private_t *mydata; + + mydata = (private_t *)malloc(sizeof(private_t)); + if (mydata == NULL) + return SIO_ERR_MEM; + + mydata->inputsize = 0; + mydata->outputsize = 0; + + *u = mydata; + + return SIO_OK; +} + +/* + * configure stage + * + * pass two void pointers + */ +static +sio_rc_t buffer_configure(sio_t *sio, void *u, void *obj, void *val) +{ + private_t *mydata = (private_t *)u; + const char *name = (const char *)obj; + + if (!strcmp(name, "inputsize")) { + mydata->inputsize = *(size_t *)val; + } else if (!strcmp(name, "outputsize")) { + mydata->outputsize = *(size_t *)val; + } else { + return SIO_ERR_ARG; + } + + return SIO_OK; +} + +/* + * destroy stage + */ +static +sio_rc_t buffer_cleanup(sio_t *sio, void *u) +{ + private_t *mydata = (private_t *)u; + + free(mydata); + + return SIO_OK; +} + +static +sio_rc_t buffer_openr(sio_t *sio, al_t *al, void *u) +{ + private_t *mydata = (private_t *)u; + al_rc_t arc; + + arc = al_create(&mydata->input); + if (arc != AL_OK) + return SIO_ERR_INT; + + return SIO_OK; +} + +static +sio_rc_t buffer_closer(sio_t *sio, al_t *al, void *u) +{ + private_t *mydata = (private_t *)u; + + al_destroy(mydata->input); + mydata->input = NULL; + + return SIO_OK; +} + +static +sio_rc_t buffer_openw(sio_t *sio, al_t *al, void *u) +{ + private_t *mydata = (private_t *)u; + al_rc_t arc; + + arc = al_txalloc(al, &mydata->outputtx); + if (arc != AL_OK) + return SIO_ERR_INT; + + arc = al_create(&mydata->output); + if (arc != AL_OK) { + al_txfree(al, mydata->outputtx); + return SIO_ERR_INT; + } + + return SIO_OK; +} + +static +sio_rc_t buffer_closew(sio_t *sio, al_t *al, void *u) +{ + private_t *mydata = (private_t *)u; + + al_destroy(mydata->output); + mydata->output = NULL; + al_txfree(al, mydata->outputtx); + mydata->outputtx = NULL; + + return SIO_OK; +} + +static +sio_rc_t buffer_inout(sio_t *sio, al_t *al, al_t *buf, size_t size, + sio_rc_t up, sio_rc_t down) +{ + size_t avail, data, needed; + al_rc_t arc; + al_label_t label; + + arc = al_splice(buf, al_bytes(buf), 0, al, NULL); + if (arc != AL_OK) + return SIO_ERR_INT; + + avail = al_bytes(buf); + if (avail <= 0) + return down; + + arc = al_firstlabel(buf, 0, 1, AL_FORWARD, NULL, &label); + if (arc != AL_OK) + return SIO_ERR_INT; + + al_flatten(buf, 0, avail, AL_FORWARD_SPAN, label, NULL, &data); + + needed = size; + if (data < avail) + needed = 1; + + if (data >= needed) { + if (data >= size) + data = size; + al_splice(buf, 0, data, NULL, al); + return up; + } + + return down; +} + +static +sio_rc_t buffer_input(sio_t *sio, al_t *al, void *u) +{ + private_t *mydata = (private_t *)u; + + return buffer_inout(sio, al, mydata->input, mydata->inputsize, + SIO_DOWNSTREAM, SIO_UPSTREAM); +} + +static +sio_rc_t buffer_output(sio_t *sio, al_t *al, void *u) +{ + private_t *mydata = (private_t *)u; + + return buffer_inout(sio, al, mydata->output, mydata->outputsize, + SIO_UPSTREAM, SIO_DOWNSTREAM); +} + +sio_module_t sio_module_buffer = { + "buffer", + buffer_init, + buffer_configure, + buffer_cleanup, + buffer_openr, + buffer_closer, + buffer_openw, + buffer_closew, + buffer_input, + buffer_output +}; + Index: ossp-pkg/sio/sio_fd.c RCS File: /v/ossp/cvs/ossp-pkg/sio/sio_fd.c,v rcsdiff -q -kk '-r1.1' '-r1.2' -u '/v/ossp/cvs/ossp-pkg/sio/sio_fd.c,v' 2>/dev/null --- sio_fd.c 2002/10/22 12:57:20 1.1 +++ sio_fd.c 2002/10/23 17:05:10 1.2 @@ -10,10 +10,17 @@ #include "sio_module.h" typedef struct { + char *mem; + size_t size; +} buffer_t; + +typedef struct { int fd; - size_t buflen; - char *buf; - size_t actual; + buffer_t input; + size_t written; + void *label_data; + void *label_error; + void *label_eof; } private_t; /* @@ -30,9 +37,14 @@ if (mydata == NULL) return SIO_ERR_MEM; - mydata->fd = -1; - mydata->buflen = 0; - mydata->buf = NULL; + mydata->fd = -1; + + mydata->input.mem = NULL; + mydata->input.size = 0; + + sio_label(sio, SIO_LN_DATA, &mydata->label_data); + sio_label(sio, SIO_LN_ERROR, &mydata->label_error); + sio_label(sio, SIO_LN_EOF, &mydata->label_eof); *u = mydata; @@ -44,20 +56,15 @@ * */ static -sio_rc_t fd_configure(sio_t *sio, void *u, void *obj, void *value) +sio_rc_t fd_configure(sio_t *sio, void *u, void *obj, void *val) { private_t *mydata = (private_t *)u; const char *name = (const char *)obj; - char *newbuf; if (!strcmp(name, "fd")) { - mydata->fd = *(int *)value; + mydata->fd = *(int *)val; } else if (!strcmp(name, "buflen")) { - mydata->buflen = *(int *)value; - newbuf = realloc(mydata->buf, mydata->buflen); - if (newbuf == NULL) - return SIO_ERR_MEM; - mydata->buf = newbuf; + mydata->input.size = *(size_t *)val; } else { return SIO_ERR_ARG; } @@ -71,22 +78,50 @@ static sio_rc_t fd_cleanup(sio_t *sio, void *u) { + return SIO_OK; +} + +static +sio_rc_t fd_openr(sio_t *sio, al_t *al, void *u) +{ + private_t *mydata = (private_t *)u; + buffer_t *buf = &mydata->input; + char *p; + size_t n; + + n = buf->size; + p = realloc(buf->mem, n); + if (p != NULL) + buf->mem = p; + + if (buf->mem == NULL) + return SIO_ERR_MEM; + + return SIO_OK; +} + +static +sio_rc_t fd_closer(sio_t *sio, al_t *al, void *u) +{ private_t *mydata = (private_t *)u; + buffer_t *buf = &mydata->input; - if (mydata->buf) free(mydata->buf); - free(mydata); + if (buf->mem != NULL) { + free(buf->mem); + buf->mem = NULL; + } return SIO_OK; } static -sio_rc_t fd_open(sio_t *sio, void *u) +sio_rc_t fd_openw(sio_t *sio, al_t *al, void *u) { return SIO_OK; } static -sio_rc_t fd_close(sio_t *sio, void *u) +sio_rc_t fd_closew(sio_t *sio, al_t *al, void *u) { return SIO_OK; } @@ -95,18 +130,21 @@ sio_rc_t fd_input(sio_t *sio, al_t *al, void *u) { private_t *mydata = (private_t *)u; + buffer_t *buf = &mydata->input; size_t actual; - if (mydata->buf == NULL) - return SIO_ERR_ARG; - - actual = read(mydata->fd, mydata->buf, mydata->buflen); - if (actual < 0) - return SIO_ERR_SYS; + actual = read(mydata->fd, buf->mem, buf->size); + if (actual < 0) { + al_append_bytes(al, NULL, 0, mydata->label_error); + return SIO_OK; + } else if (actual == 0) { + al_append_bytes(al, NULL, 0, mydata->label_eof); + return SIO_OK; + } - al_append_bytes(al, mydata->buf, actual); + al_append_bytes(al, buf->mem, actual, mydata->label_data); - return SIO_OK; + return SIO_DOWNSTREAM; } static @@ -123,7 +161,7 @@ if (actual < 0) return AL_ERR_EOF; - mydata->actual += actual; + mydata->written += actual; return AL_OK; } @@ -135,24 +173,27 @@ al_rc_t arc; size_t n = al_bytes(al); - mydata->actual = 0; + mydata->written = 0; - arc = al_traverse_cb(al, 0, n, AL_FORWARD, fd_output_chunk, u); + arc = al_traverse_cb(al, 0, n, AL_FORWARD, mydata->label_data, + fd_output_chunk, u); if (arc != AL_OK) return SIO_ERR_INT; - arc = al_splice(al, 0, mydata->actual, NULL, NULL); + arc = al_splice(al, 0, mydata->written, NULL, NULL); if (arc != AL_OK) return SIO_ERR_INT; - return SIO_OK; + return SIO_DOWNSTREAM; } -sio_module_t sio_fd_module = { +sio_module_t sio_module_fd = { "fd", fd_init, fd_configure, fd_cleanup, - fd_open, - fd_close, + fd_openr, + fd_closer, + fd_openw, + fd_closew, fd_input, fd_output }; Index: ossp-pkg/sio/sio_hole.c RCS File: /v/ossp/cvs/ossp-pkg/sio/sio_hole.c,v co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/sio/sio_hole.c,v' | diff -u /dev/null - -L'ossp-pkg/sio/sio_hole.c' 2>/dev/null --- ossp-pkg/sio/sio_hole.c +++ - 2025-10-23 06:07:09.407205611 +0200 @@ -0,0 +1,113 @@ +#include +#include + +#include "al.h" +#include "sio.h" +#include "sio_module.h" + +typedef struct { +} private_t; + +/* + * create stage + * + * allocate private instance data + */ +static +sio_rc_t hole_init(sio_t *sio, void **u) +{ + private_t *mydata; + + mydata = (private_t *)malloc(sizeof(private_t)); + if (mydata == NULL) + return SIO_ERR_MEM; + + *u = mydata; + + return SIO_OK; +} + +/* + * configure stage + * + * pass two void pointers + */ +static +sio_rc_t hole_configure(sio_t *sio, void *u, void *obj, void *val) +{ + return SIO_ERR_ARG; +} + +/* + * destroy stage + */ +static +sio_rc_t hole_cleanup(sio_t *sio, void *u) +{ + private_t *mydata = (private_t *)u; + + free(mydata); + + return SIO_OK; +} + +static +sio_rc_t hole_openr(sio_t *sio, al_t *al, void *u) +{ + return SIO_OK; +} + +static +sio_rc_t hole_closer(sio_t *sio, al_t *al, void *u) +{ + return SIO_OK; +} + +static +sio_rc_t hole_openw(sio_t *sio, al_t *al, void *u) +{ + return SIO_OK; +} + +static +sio_rc_t hole_closew(sio_t *sio, al_t *al, void *u) +{ + return SIO_OK; +} + +static +sio_rc_t hole_input(sio_t *sio, al_t *al, void *u) +{ + size_t feed = al_bytes(al); + + /* drop all data into the bit bucket */ + if (feed > 0) { + al_splice(al, 0, feed, NULL, NULL); + return SIO_DOWNSTREAM; + } + + return SIO_UPSTREAM; +} + +static +sio_rc_t hole_output(sio_t *sio, al_t *al, void *u) +{ + /* drop all data into the bit bucket */ + al_splice(al, 0, al_bytes(al), NULL, NULL); + + return SIO_DOWNSTREAM; +} + +sio_module_t sio_module_hole = { + "hole", + hole_init, + hole_configure, + hole_cleanup, + hole_openr, + hole_closer, + hole_openw, + hole_closew, + hole_input, + hole_output +}; + Index: ossp-pkg/sio/sio_module.h RCS File: /v/ossp/cvs/ossp-pkg/sio/Attic/sio_module.h,v rcsdiff -q -kk '-r1.1' '-r1.2' -u '/v/ossp/cvs/ossp-pkg/sio/Attic/sio_module.h,v' 2>/dev/null --- sio_module.h 2002/10/22 12:57:20 1.1 +++ sio_module.h 2002/10/23 17:05:10 1.2 @@ -3,9 +3,18 @@ sio_rc_t (*init) (sio_t *, void **); sio_rc_t (*configure) (sio_t *, void *, void *, void *); sio_rc_t (*cleanup) (sio_t *, void *); - sio_rc_t (*open) (sio_t *, void *); - sio_rc_t (*close) (sio_t *, void *); + sio_rc_t (*openr) (sio_t *, al_t *, void *); + sio_rc_t (*closer) (sio_t *, al_t *, void *); + sio_rc_t (*openw) (sio_t *, al_t *, void *); + sio_rc_t (*closew) (sio_t *, al_t *, void *); sio_rc_t (*input) (sio_t *, al_t *, void *); sio_rc_t (*output) (sio_t *, al_t *, void *); }; +typedef enum { + SIO_LN_DATA, + SIO_LN_ERROR, + SIO_LN_EOF +} sio_labelnum_t; + +sio_rc_t sio_label(sio_t *, sio_labelnum_t label, void **labelp); Index: ossp-pkg/sio/sio_null.c RCS File: /v/ossp/cvs/ossp-pkg/sio/sio_null.c,v rcsdiff -q -kk '-r1.1' '-r1.2' -u '/v/ossp/cvs/ossp-pkg/sio/sio_null.c,v' 2>/dev/null --- sio_null.c 2002/10/22 12:57:20 1.1 +++ sio_null.c 2002/10/23 17:05:10 1.2 @@ -63,36 +63,50 @@ } static -sio_rc_t null_open(sio_t *sio, void *u) +sio_rc_t null_openr(sio_t *sio, al_t *al, void *u) { return SIO_OK; } static -sio_rc_t null_close(sio_t *sio, void *u) +sio_rc_t null_closer(sio_t *sio, al_t *al, void *u) { return SIO_OK; } static -sio_rc_t null_input(sio_t *sio, al_t *al, void *u) +sio_rc_t null_openw(sio_t *sio, al_t *al, void *u) { return SIO_OK; } static -sio_rc_t null_output(sio_t *sio, al_t *al, void *u) +sio_rc_t null_closew(sio_t *sio, al_t *al, void *u) { return SIO_OK; } -sio_module_t sio_null_module = { +static +sio_rc_t null_input(sio_t *sio, al_t *al, void *u) +{ + return SIO_DOWNSTREAM; +} + +static +sio_rc_t null_output(sio_t *sio, al_t *al, void *u) +{ + return SIO_UPSTREAM; +} + +sio_module_t sio_module_null = { "null", null_init, null_configure, null_cleanup, - null_open, - null_close, + null_openr, + null_closer, + null_openw, + null_closew, null_input, null_output }; Index: ossp-pkg/sio/sio_test.c RCS File: /v/ossp/cvs/ossp-pkg/sio/sio_test.c,v co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/sio/sio_test.c,v' | diff -u /dev/null - -L'ossp-pkg/sio/sio_test.c' 2>/dev/null --- ossp-pkg/sio/sio_test.c +++ - 2025-10-23 06:07:09.417642273 +0200 @@ -0,0 +1,46 @@ +#include + +#include "al.h" +#include "sio.h" + +extern sio_module_t sio_module_fd; +extern sio_module_t sio_module_buffer; + +#define e(f) rc = f; printf("%s = %s\n",#f, sio_error(rc)); fflush(stdout); + +int main(int argc, char *argv[]) +{ + sio_rc_t rc; + sio_t *sio; + sio_stage_t *sios_fd, *sios_buffer; + int fd; + char buf[] = "Hello world\n"; + size_t actual; + size_t buflen = 1000; + + fd = fileno(stdout); + + e(sio_create(&sio)); + + e(sio_create_stage(sio, &sio_module_buffer, &sios_buffer)); + e(sio_configure_stage(sio, sios_buffer, "outputsize", &buflen)); + e(sio_create_stage(sio, &sio_module_fd, &sios_fd)); + e(sio_configure_stage(sio, sios_fd, "fd", &fd)); + + e(sio_attach(sio, sios_buffer, SIO_MODE_WRITE)); + e(sio_attach(sio, sios_fd, SIO_MODE_WRITE)); + + e(sio_write(sio, buf, sizeof(buf)-1, &actual)); + + e(sio_push(sio)); + + e(sio_detach(sio, sios_fd)); + e(sio_detach(sio, sios_buffer)); + + e(sio_destroy_stage(sio, sios_fd)); + e(sio_destroy_stage(sio, sios_buffer)); + + e(sio_destroy(sio)); + + return 0; +}