From: Martin Willi Date: Mon, 1 Jul 2013 08:36:52 +0000 (+0200) Subject: stream: add read/write_all() methods to stream X-Git-Tag: 5.1.0rc1~10^2~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d57b9e7c822149828ef6ce1467be60c28f011019;p=thirdparty%2Fstrongswan.git stream: add read/write_all() methods to stream --- diff --git a/src/libstrongswan/networking/streams/stream.c b/src/libstrongswan/networking/streams/stream.c index 9a4a3d3103..20379fb415 100644 --- a/src/libstrongswan/networking/streams/stream.c +++ b/src/libstrongswan/networking/streams/stream.c @@ -54,8 +54,6 @@ struct private_stream_t { * Data for write-ready callback */ void *write_data; - - }; METHOD(stream_t, read_, ssize_t, @@ -86,6 +84,29 @@ METHOD(stream_t, read_, ssize_t, } } +METHOD(stream_t, read_all, bool, + private_stream_t *this, void *buf, size_t len) +{ + ssize_t ret; + + while (len) + { + ret = read_(this, buf, len, TRUE); + if (ret < 0) + { + return FALSE; + } + if (ret == 0) + { + errno = ECONNRESET; + return FALSE; + } + len -= ret; + buf += ret; + } + return TRUE; +} + METHOD(stream_t, write_, ssize_t, private_stream_t *this, void *buf, size_t len, bool block) { @@ -114,6 +135,29 @@ METHOD(stream_t, write_, ssize_t, } } +METHOD(stream_t, write_all, bool, + private_stream_t *this, void *buf, size_t len) +{ + ssize_t ret; + + while (len) + { + ret = write_(this, buf, len, TRUE); + if (ret < 0) + { + return FALSE; + } + if (ret == 0) + { + errno = ECONNRESET; + return FALSE; + } + len -= ret; + buf += ret; + } + return TRUE; +} + /** * Remove a registered watcher */ @@ -236,8 +280,10 @@ stream_t *stream_create_from_fd(int fd) INIT(this, .public = { .read = _read_, + .read_all = _read_all, .on_read = _on_read, .write = _write_, + .write_all = _write_all, .on_write = _on_write, .get_file = _get_file, .destroy = _destroy, diff --git a/src/libstrongswan/networking/streams/stream.h b/src/libstrongswan/networking/streams/stream.h index 17e5a94bef..8cd8419c30 100644 --- a/src/libstrongswan/networking/streams/stream.h +++ b/src/libstrongswan/networking/streams/stream.h @@ -71,6 +71,19 @@ struct stream_t { */ ssize_t (*read)(stream_t *this, void *buf, size_t len, bool block); + /** + * Read data from the stream, avoiding short reads. + * + * This call is always blocking, and reads until len has been read + * completely. If the connection is closed before enough bytes could be + * returned, errno is set to ECONNRESET. + * + * @param buf data buffer to read into + * @param len number of bytes to read + * @return TRUE if len bytes read, FALSE on error + */ + bool (*read_all)(stream_t *this, void *buf, size_t len); + /** * Register a callback to invoke when stream has data to read. * @@ -92,6 +105,18 @@ struct stream_t { */ ssize_t (*write)(stream_t *this, void *buf, size_t len, bool block); + /** + * Write data to the stream, avoiding short writes. + * + * This call is always blocking, and writes until len bytes has been + * written. + * + * @param buf data buffer to write + * @param len number of bytes to write + * @return TRUE if len bytes written, FALSE on error + */ + bool (*write_all)(stream_t *this, void *buf, size_t len); + /** * Register a callback to invoke when a write would not block. *