PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pg_iovec.h
Go to the documentation of this file.
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. */
28struct 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 */
47static inline ssize_t
48pg_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 if (iovcnt == 1)
56 return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
57 else
58 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 */
86static inline ssize_t
87pg_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 if (iovcnt == 1)
95 return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
96 else
97 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 */
int i
Definition: isn.c:77
static ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pg_iovec.h:87
static ssize_t pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pg_iovec.h:48
#define pg_pwrite
Definition: port.h:227
#define pg_pread
Definition: port.h:226
static int fd(const char *x, int i)
Definition: preproc-init.c:105