Index: ossp-pkg/sio/sio_bio.c RCS File: /v/ossp/cvs/ossp-pkg/sio/sio_bio.c,v rcsdiff -q -kk '-r1.1' '-r1.2' -u '/v/ossp/cvs/ossp-pkg/sio/sio_bio.c,v' 2>/dev/null --- 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; tbio, 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);