LCOV - code coverage report
Current view: top level - src/include/port - pg_iovec.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 8 8
Test Date: 2026-03-01 01:14:39 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            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      1603112 : 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      1603112 :     if (iovcnt == 1)
      62      1602587 :         return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
      63              :     else
      64          525 :         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              : }
      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      1009529 : 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      1009529 :     if (iovcnt == 1)
     101       983690 :         return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
     102              :     else
     103        25839 :         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              : }
     126              : 
     127              : #endif                          /* PG_IOVEC_H */
        

Generated by: LCOV version 2.0-1