diff options
Diffstat (limited to 'lib/libfetch/common.c')
-rw-r--r-- | lib/libfetch/common.c | 41 |
1 files changed, 34 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); } |