LCOV - code coverage report
Current view: top level - src/include/port - pg_iovec.h (source / functions) Hit Total Coverage
Test: PostgreSQL 19devel Lines: 8 8 100.0 %
Date: 2025-07-27 12:18:32 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             : /* 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     3029060 : pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_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     3029060 :     if (iovcnt == 1)
      62     3027176 :         return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
      63             :     else
      64        1884 :         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     1965136 : pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_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     1965136 :     if (iovcnt == 1)
     101     1913724 :         return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
     102             :     else
     103       51412 :         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 1.16