LCOV - code coverage report
Current view: top level - lib/util - iov_buf.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 39 43 90.7 %
Date: 2021-09-23 10:06:22 Functions: 4 4 100.0 %

          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             : #include "replace.h"
      21             : #include "system/filesys.h"
      22             : #include "iov_buf.h"
      23             : #include <talloc.h>
      24             : 
      25     7387814 : ssize_t iov_buflen(const struct iovec *iov, int iovcnt)
      26             : {
      27     7387814 :         return iov_buf(iov, iovcnt, NULL, 0);
      28             : }
      29             : 
      30     8674692 : ssize_t iov_buf(const struct iovec *iov, int iovcnt,
      31             :                 uint8_t *buf, size_t buflen)
      32             : {
      33     8674692 :         size_t needed = 0;
      34     8674692 :         uint8_t *p = buf;
      35             :         int i;
      36             : 
      37    37848540 :         for (i=0; i<iovcnt; i++) {
      38    29173848 :                 size_t thislen = iov[i].iov_len;
      39             :                 size_t tmp;
      40             : 
      41    29173848 :                 tmp = needed + thislen;
      42             : 
      43    29173848 :                 if (tmp < needed) {
      44             :                         /* wrap */
      45           0 :                         return -1;
      46             :                 }
      47    29173848 :                 needed = tmp;
      48             : 
      49    29173848 :                 if ((p != NULL) && needed <= buflen && thislen > 0) {
      50     4289479 :                         memcpy(p, iov[i].iov_base, thislen);
      51     4173656 :                         p += thislen;
      52             :                 }
      53             :         }
      54             : 
      55     8674692 :         return needed;
      56             : }
      57             : 
      58    26207245 : bool iov_advance(struct iovec **iov, int *iovcnt, size_t n)
      59             : {
      60    26207245 :         struct iovec *v = *iov;
      61    26207245 :         int cnt = *iovcnt;
      62             : 
      63    77564356 :         while (n > 0) {
      64    41185780 :                 if (cnt == 0) {
      65           0 :                         return false;
      66             :                 }
      67    41185780 :                 if (n < v->iov_len) {
      68    12057765 :                         v->iov_base = (char *)v->iov_base + n;
      69    12057765 :                         v->iov_len -= n;
      70    12057765 :                         break;
      71             :                 }
      72    29128015 :                 n -= v->iov_len;
      73    29128015 :                 v += 1;
      74    29128015 :                 cnt -= 1;
      75             :         }
      76             : 
      77             :         /*
      78             :          * Skip 0-length iovec's
      79             :          *
      80             :          * There might be empty buffers at the end of iov. Next time we do a
      81             :          * readv/writev based on this iov would give 0 transferred bytes, also
      82             :          * known as EPIPE. So we need to be careful discarding them.
      83             :          */
      84             : 
      85    49999738 :         while ((cnt > 0) && (v->iov_len == 0)) {
      86     1658936 :                 v += 1;
      87     1658936 :                 cnt -= 1;
      88             :         }
      89             : 
      90    26207245 :         *iov = v;
      91    26207245 :         *iovcnt = cnt;
      92    26207245 :         return true;
      93             : }
      94             : 
      95     1067362 : uint8_t *iov_concat(TALLOC_CTX *mem_ctx, const struct iovec *iov, int count)
      96             : {
      97             :         ssize_t buflen;
      98             :         uint8_t *buf;
      99             : 
     100     1067362 :         buflen = iov_buflen(iov, count);
     101     1067362 :         if (buflen == -1) {
     102           0 :                 return NULL;
     103             :         }
     104             : 
     105     1067362 :         buf = talloc_array(mem_ctx, uint8_t, buflen);
     106     1067362 :         if (buf == NULL) {
     107           0 :                 return NULL;
     108             :         }
     109             : 
     110     1067362 :         iov_buf(iov, count, buf, buflen);
     111             : 
     112     1067362 :         return buf;
     113             : }

Generated by: LCOV version 1.13