diff options
-rw-r--r-- | lib/libfetch/common.c | 41 | ||||
-rw-r--r-- | lib/libfetch/common.h | 4 |
2 files changed, 38 insertions, 7 deletions
diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c index 48ac5d3..ab3f4ca 100644 --- a/lib/libfetch/common.c +++ b/lib/libfetch/common.c @@ -454,6 +454,20 @@ _fetch_getln(conn_t *conn) ssize_t _fetch_write(conn_t *conn, const char *buf, size_t len) { + struct iovec iov; + + iov.iov_base = (char *)buf; + iov.iov_len = len; + return _fetch_writev(conn, &iov, 1); +} + +/* + * Write a vector to a connection w/ timeout + * Note: can modify the iovec. + */ +ssize_t +_fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt) +{ struct timeval now, timeout, wait; fd_set writefds; ssize_t wlen, total; @@ -466,7 +480,7 @@ _fetch_write(conn_t *conn, const char *buf, size_t len) } total = 0; - while (len > 0) { + while (iovcnt > 0) { while (fetchTimeout && !FD_ISSET(conn->sd, &writefds)) { FD_SET(conn->sd, &writefds); gettimeofday(&now, NULL); @@ -492,10 +506,11 @@ _fetch_write(conn_t *conn, const char *buf, size_t len) errno = 0; #ifdef WITH_SSL if (conn->ssl != NULL) - wlen = SSL_write(conn->ssl, buf, len); + wlen = SSL_write(conn->ssl, + iov->iov_base, iov->iov_len); else #endif - wlen = write(conn->sd, buf, len); + wlen = writev(conn->sd, iov, iovcnt); if (wlen == 0) { /* we consider a short write a failure */ errno = EPIPE; @@ -507,9 +522,17 @@ _fetch_write(conn_t *conn, const char *buf, size_t len) continue; return (-1); } - len -= wlen; - buf += wlen; total += wlen; + while (iovcnt > 0 && wlen > iov->iov_len) { + wlen -= iov->iov_len; + iov++; + iovcnt--; + } + if (iovcnt > 0) { + iov->iov_len -= wlen; + iov->iov_base += wlen; + wlen = 0; + } } return (total); } @@ -521,10 +544,14 @@ _fetch_write(conn_t *conn, const char *buf, size_t len) int _fetch_putln(conn_t *conn, const char *str, size_t len) { + struct iovec iov[2]; DEBUG(fprintf(stderr, ">>> %s\n", str)); - if (_fetch_write(conn, str, len) == -1 || - _fetch_write(conn, ENDL, sizeof ENDL) == -1) + iov[0].iov_base = (char *)str; + iov[0].iov_len = len; + iov[1].iov_base = (char *)ENDL; + iov[1].iov_len = sizeof ENDL; + if (_fetch_writev(conn, iov, 2) == -1) return (-1); return (0); } diff --git a/lib/libfetch/common.h b/lib/libfetch/common.h index 42f68a8..4b42bf2 100644 --- a/lib/libfetch/common.h +++ b/lib/libfetch/common.h @@ -68,6 +68,9 @@ struct fetcherr { const char *string; }; +/* for _fetch_writev */ +struct iovec; + void _fetch_seterr(struct fetcherr *, int); void _fetch_syserr(void); void _fetch_info(const char *, ...); @@ -80,6 +83,7 @@ int _fetch_ssl(conn_t *, int); ssize_t _fetch_read(conn_t *, char *, size_t); int _fetch_getln(conn_t *); ssize_t _fetch_write(conn_t *, const char *, size_t); +ssize_t _fetch_writev(conn_t *, struct iovec *, int); int _fetch_putln(conn_t *, const char *, size_t); int _fetch_close(conn_t *); int _fetch_add_entry(struct url_ent **, int *, int *, |