Line data Source code
1 : /* 2 : * Unix SMB/CIFS implementation. 3 : * Samba system utilities 4 : * Copyright (C) Volker Lendecke 2014 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 3 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 : */ 19 : 20 : #ifndef __LIB_IOV_BUF_H__ 21 : #define __LIB_IOV_BUF_H__ 22 : 23 : #include "replace.h" 24 : #include <talloc.h> 25 : #include "system/filesys.h" 26 : 27 : static inline 28 8853142 : ssize_t iov_buf(const struct iovec *iov, int iovcnt, 29 : uint8_t *buf, size_t buflen) 30 : { 31 8853142 : size_t needed = 0; 32 8853142 : uint8_t *p = buf; 33 277569 : int i; 34 : 35 39029696 : for (i=0; i<iovcnt; i++) { 36 30176554 : size_t thislen = iov[i].iov_len; 37 766381 : size_t tmp; 38 : 39 30176554 : tmp = needed + thislen; 40 : 41 30176554 : if (tmp < needed) { 42 : /* wrap */ 43 0 : return -1; 44 : } 45 30176554 : needed = tmp; 46 : 47 30176554 : if ((p != NULL) && needed <= buflen && thislen > 0) { 48 4409618 : memcpy(p, iov[i].iov_base, thislen); 49 4409618 : p += thislen; 50 : } 51 : } 52 : 53 8853142 : return needed; 54 : } 55 : 56 : static inline 57 7506913 : ssize_t iov_buflen(const struct iovec *iov, int iovcnt) 58 : { 59 7506913 : return iov_buf(iov, iovcnt, NULL, 0); 60 : } 61 : 62 : static inline 63 31460217 : bool iov_advance(struct iovec **iov, int *iovcnt, size_t n) 64 : { 65 31460217 : struct iovec *v = *iov; 66 31460217 : int cnt = *iovcnt; 67 : 68 70582201 : while (n > 0) { 69 49481163 : if (cnt == 0) { 70 0 : return false; 71 : } 72 49481163 : if (n < v->iov_len) { 73 10359179 : v->iov_base = (char *)v->iov_base + n; 74 10359179 : v->iov_len -= n; 75 10359179 : break; 76 : } 77 39121984 : n -= v->iov_len; 78 39121984 : v += 1; 79 39121984 : cnt -= 1; 80 : } 81 : 82 : /* 83 : * Skip 0-length iovec's 84 : * 85 : * There might be empty buffers at the end of iov. Next time we do a 86 : * readv/writev based on this iov would give 0 transferred bytes, also 87 : * known as EPIPE. So we need to be careful discarding them. 88 : */ 89 : 90 33162925 : while ((cnt > 0) && (v->iov_len == 0)) { 91 1702708 : v += 1; 92 1702708 : cnt -= 1; 93 : } 94 : 95 31460217 : *iov = v; 96 31460217 : *iovcnt = cnt; 97 31460217 : return true; 98 : } 99 : 100 : uint8_t *iov_concat(TALLOC_CTX *mem_ctx, const struct iovec *iov, int count); 101 : 102 : #endif