LCOV - code coverage report
Current view: top level - src/include/port - pg_iovec.h (source / functions) Coverage Total Hit
Test: Code coverage Lines: 100.0 % 10 10
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 100.0 % 4 4

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * pg_iovec.h
       4                 :             :  *        Header for vectored I/O functions, to use in place of <sys/uio.h>.
       5                 :             :  *
       6                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :             :  *
       9                 :             :  * src/include/port/pg_iovec.h
      10                 :             :  *
      11                 :             :  *-------------------------------------------------------------------------
      12                 :             :  */
      13                 :             : #ifndef PG_IOVEC_H
      14                 :             : #define PG_IOVEC_H
      15                 :             : 
      16                 :             : #ifndef WIN32
      17                 :             : 
      18                 :             : #include <limits.h>
      19                 :             : #include <sys/uio.h>                      /* IWYU pragma: export */
      20                 :             : #include <unistd.h>
      21                 :             : 
      22                 :             : #else
      23                 :             : 
      24                 :             : /* Define our own POSIX-compatible iovec struct. */
      25                 :             : struct iovec
      26                 :             : {
      27                 :             :         void       *iov_base;
      28                 :             :         size_t          iov_len;
      29                 :             : };
      30                 :             : 
      31                 :             : #endif
      32                 :             : 
      33                 :             : /*
      34                 :             :  * If <limits.h> didn't define IOV_MAX, define our own.  X/Open requires at
      35                 :             :  * least 16.  (GNU Hurd apparently feel that they're not bound by X/Open,
      36                 :             :  * because they don't define this symbol at all.)
      37                 :             :  */
      38                 :             : #ifndef IOV_MAX
      39                 :             : #define IOV_MAX 16
      40                 :             : #endif
      41                 :             : 
      42                 :             : /*
      43                 :             :  * Define a reasonable maximum that is safe to use on the stack in arrays of
      44                 :             :  * struct iovec and other small types.  The operating system could limit us to
      45                 :             :  * a number as low as 16, but most systems have 1024.
      46                 :             :  */
      47                 :             : #define PG_IOV_MAX Min(IOV_MAX, 128)
      48                 :             : 
      49                 :             : /*
      50                 :             :  * Like preadv(), but with a prefix to remind us of a side-effect: on Windows
      51                 :             :  * this changes the current file position.
      52                 :             :  */
      53                 :             : static inline ssize_t
      54                 :       41416 : pg_preadv(int fd, const struct iovec *iov, int iovcnt, pgoff_t offset)
      55                 :             : {
      56                 :             : #if HAVE_DECL_PREADV
      57                 :             :         /*
      58                 :             :          * Avoid a small amount of argument copying overhead in the kernel if
      59                 :             :          * there is only one iovec.
      60                 :             :          */
      61         [ +  + ]:       41416 :         if (iovcnt == 1)
      62                 :       41318 :                 return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
      63                 :             :         else
      64                 :          98 :                 return preadv(fd, iov, iovcnt, offset);
      65                 :             : #else
      66                 :             :         ssize_t         sum = 0;
      67                 :             :         ssize_t         part;
      68                 :             : 
      69                 :             :         for (int i = 0; i < iovcnt; ++i)
      70                 :             :         {
      71                 :             :                 part = pg_pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
      72                 :             :                 if (part < 0)
      73                 :             :                 {
      74                 :             :                         if (i == 0)
      75                 :             :                                 return -1;
      76                 :             :                         else
      77                 :             :                                 return sum;
      78                 :             :                 }
      79                 :             :                 sum += part;
      80                 :             :                 offset += part;
      81                 :             :                 if ((size_t) part < iov[i].iov_len)
      82                 :             :                         return sum;
      83                 :             :         }
      84                 :             :         return sum;
      85                 :             : #endif
      86                 :       41416 : }
      87                 :             : 
      88                 :             : /*
      89                 :             :  * Like pwritev(), but with a prefix to remind us of a side-effect: on Windows
      90                 :             :  * this changes the current file position.
      91                 :             :  */
      92                 :             : static inline ssize_t
      93                 :       81602 : pg_pwritev(int fd, const struct iovec *iov, int iovcnt, pgoff_t offset)
      94                 :             : {
      95                 :             : #if HAVE_DECL_PWRITEV
      96                 :             :         /*
      97                 :             :          * Avoid a small amount of argument copying overhead in the kernel if
      98                 :             :          * there is only one iovec.
      99                 :             :          */
     100         [ +  + ]:       81602 :         if (iovcnt == 1)
     101                 :       80602 :                 return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
     102                 :             :         else
     103                 :        1000 :                 return pwritev(fd, iov, iovcnt, offset);
     104                 :             : #else
     105                 :             :         ssize_t         sum = 0;
     106                 :             :         ssize_t         part;
     107                 :             : 
     108                 :             :         for (int i = 0; i < iovcnt; ++i)
     109                 :             :         {
     110                 :             :                 part = pg_pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
     111                 :             :                 if (part < 0)
     112                 :             :                 {
     113                 :             :                         if (i == 0)
     114                 :             :                                 return -1;
     115                 :             :                         else
     116                 :             :                                 return sum;
     117                 :             :                 }
     118                 :             :                 sum += part;
     119                 :             :                 offset += part;
     120                 :             :                 if ((size_t) part < iov[i].iov_len)
     121                 :             :                         return sum;
     122                 :             :         }
     123                 :             :         return sum;
     124                 :             : #endif
     125                 :       81602 : }
     126                 :             : 
     127                 :             : #endif                                                  /* PG_IOVEC_H */
        

Generated by: LCOV version 2.3.2-1