diff options
-rw-r--r-- | source3/include/proto.h | 1 | ||||
-rw-r--r-- | source3/lib/util_sock.c | 69 |
2 files changed, 70 insertions, 0 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index f1be1874bf..08260517ff 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1441,6 +1441,7 @@ NTSTATUS read_socket_with_timeout(int fd, char *buf, size_t *size_ret); NTSTATUS read_data(int fd, char *buffer, size_t N); ssize_t write_data(int fd, const char *buffer, size_t N); +ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt); bool send_keepalive(int client); NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf, unsigned int timeout, diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 7fe8ed82a2..a362938fd3 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -635,6 +635,75 @@ NTSTATUS read_data(int fd, char *buffer, size_t N) } /**************************************************************************** + Write all data from an iov array +****************************************************************************/ + +ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt) +{ + int i; + size_t to_send; + ssize_t thistime; + size_t sent; + struct iovec *iov_copy, *iov; + + to_send = 0; + for (i=0; i<iovcnt; i++) { + to_send += orig_iov[i].iov_len; + } + + thistime = sys_writev(fd, orig_iov, iovcnt); + if ((thistime <= 0) || (thistime == to_send)) { + return thistime; + } + sent = thistime; + + /* + * We could not send everything in one call. Make a copy of iov that + * we can mess with. We keep a copy of the array start in iov_copy for + * the TALLOC_FREE, because we're going to modify iov later on, + * discarding elements. + */ + + iov_copy = (struct iovec *)TALLOC_MEMDUP( + talloc_tos(), orig_iov, sizeof(struct iovec) * iovcnt); + + if (iov_copy == NULL) { + errno = ENOMEM; + return -1; + } + iov = iov_copy; + + while (sent < to_send) { + /* + * We have to discard "thistime" bytes from the beginning + * iov array, "thistime" contains the number of bytes sent + * via writev last. + */ + while (thistime > 0) { + if (thistime < iov[0].iov_len) { + char *new_base = + (char *)iov[0].iov_base + thistime; + iov[0].iov_base = new_base; + iov[0].iov_len -= thistime; + break; + } + thistime -= iov[0].iov_len; + iov += 1; + iovcnt -= 1; + } + + thistime = sys_writev(fd, iov, iovcnt); + if (thistime <= 0) { + break; + } + sent += thistime; + } + + TALLOC_FREE(iov_copy); + return sent; +} + +/**************************************************************************** Write data to a fd. ****************************************************************************/ |