diff options
author | Volker Lendecke <vl@samba.org> | 2008-12-22 22:17:28 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2008-12-29 13:24:27 +0100 |
commit | 82a152fcf9254fe4189cac12fa3fc1744284ca13 (patch) | |
tree | 1079b369f454949777b9baaadb707ead002e1fac /source3/lib | |
parent | 6251b97e02c890b184e13187020c19c8c2e82f2c (diff) | |
download | samba-82a152fcf9254fe4189cac12fa3fc1744284ca13.tar.gz samba-82a152fcf9254fe4189cac12fa3fc1744284ca13.tar.bz2 samba-82a152fcf9254fe4189cac12fa3fc1744284ca13.zip |
Add write_data_iov
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/util_sock.c | 69 |
1 files changed, 69 insertions, 0 deletions
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. ****************************************************************************/ |