LCOV - code coverage report
Current view: top level - src/include/port - pg_iovec.h (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 8 8 100.0 %
Date: 2025-04-01 15:15:16 Functions: 2 2 100.0 %
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-2025, 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             : /* POSIX requires at least 16 as a maximum iovcnt. */
      25             : #define IOV_MAX 16
      26             : 
      27             : /* Define our own POSIX-compatible iovec struct. */
      28             : struct iovec
      29             : {
      30             :     void       *iov_base;
      31             :     size_t      iov_len;
      32             : };
      33             : 
      34             : #endif
      35             : 
      36             : /*
      37             :  * Define a reasonable maximum that is safe to use on the stack in arrays of
      38             :  * struct iovec and other small types.  The operating system could limit us to
      39             :  * a number as low as 16, but most systems have 1024.
      40             :  */
      41             : #define PG_IOV_MAX Min(IOV_MAX, 128)
      42             : 
      43             : /*
      44             :  * Like preadv(), but with a prefix to remind us of a side-effect: on Windows
      45             :  * this changes the current file position.
      46             :  */
      47             : static inline ssize_t
      48     3021446 : pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
      49             : {
      50             : #if HAVE_DECL_PREADV
      51             :     /*
      52             :      * Avoid a small amount of argument copying overhead in the kernel if
      53             :      * there is only one iovec.
      54             :      */
      55     3021446 :     if (iovcnt == 1)
      56     3018244 :         return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
      57             :     else
      58        3202 :         return preadv(fd, iov, iovcnt, offset);
      59             : #else
      60             :     ssize_t     sum = 0;
      61             :     ssize_t     part;
      62             : 
      63             :     for (int i = 0; i < iovcnt; ++i)
      64             :     {
      65             :         part = pg_pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
      66             :         if (part < 0)
      67             :         {
      68             :             if (i == 0)
      69             :                 return -1;
      70             :             else
      71             :                 return sum;
      72             :         }
      73             :         sum += part;
      74             :         offset += part;
      75             :         if ((size_t) part < iov[i].iov_len)
      76             :             return sum;
      77             :     }
      78             :     return sum;
      79             : #endif
      80             : }
      81             : 
      82             : /*
      83             :  * Like pwritev(), but with a prefix to remind us of a side-effect: on Windows
      84             :  * this changes the current file position.
      85             :  */
      86             : static inline ssize_t
      87     1812088 : pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
      88             : {
      89             : #if HAVE_DECL_PWRITEV
      90             :     /*
      91             :      * Avoid a small amount of argument copying overhead in the kernel if
      92             :      * there is only one iovec.
      93             :      */
      94     1812088 :     if (iovcnt == 1)
      95     1762214 :         return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
      96             :     else
      97       49874 :         return pwritev(fd, iov, iovcnt, offset);
      98             : #else
      99             :     ssize_t     sum = 0;
     100             :     ssize_t     part;
     101             : 
     102             :     for (int i = 0; i < iovcnt; ++i)
     103             :     {
     104             :         part = pg_pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
     105             :         if (part < 0)
     106             :         {
     107             :             if (i == 0)
     108             :                 return -1;
     109             :             else
     110             :                 return sum;
     111             :         }
     112             :         sum += part;
     113             :         offset += part;
     114             :         if ((size_t) part < iov[i].iov_len)
     115             :             return sum;
     116             :     }
     117             :     return sum;
     118             : #endif
     119             : }
     120             : 
     121             : #endif                          /* PG_IOVEC_H */

Generated by: LCOV version 1.14