--- sio_bio.c 2002/11/19 15:54:51 1.1
+++ sio_bio.c 2002/11/19 22:29:20 1.2
@@ -12,7 +12,10 @@
size_t inputsize;
al_label_t data_label;
al_label_t eof_label;
- char eof;
+ al_label_t error_label;
+ char eof;
+ char error;
+ size_t total;
} private_t;
/*
@@ -31,9 +34,11 @@
my->bio = NULL;
my->eof = '\0';
+ my->error = '\0';
- sio_label(sio, SIO_LN_DATA, &my->data_label);
- sio_label(sio, SIO_LN_EOF, &my->eof_label);
+ sio_label(sio, SIO_LN_DATA, &my->data_label);
+ sio_label(sio, SIO_LN_EOF, &my->eof_label);
+ sio_label(sio, SIO_LN_ERROR, &my->error_label);
*u = my;
@@ -115,11 +120,19 @@
if (n == 0 || n > my->inputsize)
n = my->inputsize;
p = malloc(n);
- n = BIO_read(my->bio, p, n);
- if (n == 0 && !BIO_should_read(my->bio))
- al_append_bytes(al, &my->eof, sizeof(my->eof), my->eof_label);
- else
+ if (p != NULL)
+ do {
+ n = BIO_read(my->bio, p, n);
+ } while (n <= 0 && BIO_should_retry(my->bio));
+
+ if (p == NULL || n <= 0) {
+ free(p);
+ if (n < -1)
+ al_append_bytes(al, &my->error, sizeof(my->error), my->error_label);
+ else
+ al_append_bytes(al, &my->eof, sizeof(my->eof), my->eof_label);
+ } else
al_attach_buffer(al, p, n, my->data_label, freebiobuf, NULL);
return SIO_SCHED_DOWN;
@@ -129,17 +142,36 @@
al_rc_t siobio_write_chunk(al_chunk_t *alc, void *u)
{
private_t *my = (private_t *)u;
+ al_rc_t arc = AL_OK;
- if (al_same_label(alc, my->data_label))
- BIO_write(my->bio, al_chunk_ptr(alc, 0), al_chunk_len(alc));
+ if (al_same_label(alc, my->data_label)) {
+ char *p = al_chunk_ptr(alc, 0);
+ int n = al_chunk_len(alc);
+ int i, t;
+
+ for (t=0; t<n; t+=i) {
+ i = BIO_write(my->bio, p+t, n-t);
+ if (i <= 0) {
+ if (!BIO_should_retry(my->bio)) {
+ arc = AL_ERR_EOF;
+ break;
+ }
+ i = 0;
+ }
+ my->total += i;
+ }
+ } else {
+ my->total += al_chunk_len(alc);
+ }
- return AL_OK;
+ return arc;
}
static
sio_rc_t siobio_output(sio_t *sio, al_t *al, void *u)
{
private_t *my = (private_t *)u;
+ my->total = 0;
al_traverse_cb(al, 0, al_bytes(al), AL_FORWARD, my->data_label,
siobio_write_chunk, (void *)my);
|