summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure22
-rw-r--r--configure.ac6
-rw-r--r--src/include/port/pg_iovec.h76
-rw-r--r--src/port/meson.build2
-rw-r--r--src/port/preadv.c43
-rw-r--r--src/port/pwritev.c43
-rw-r--r--src/tools/msvc/Mkvcbuild.pm2
7 files changed, 74 insertions, 120 deletions
diff --git a/configure b/configure
index bf3ea690db3..217704e9cad 100755
--- a/configure
+++ b/configure
@@ -16057,7 +16057,7 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-# We can't use AC_REPLACE_FUNCS to replace these functions, because it
+# We can't use AC_CHECK_FUNCS to detect these functions, because it
# won't handle deployment target restrictions on macOS
ac_fn_c_check_decl "$LINENO" "preadv" "ac_cv_have_decl_preadv" "#include <sys/uio.h>
"
@@ -16070,16 +16070,6 @@ fi
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_PREADV $ac_have_decl
_ACEOF
-if test $ac_have_decl = 1; then :
-
-else
- case " $LIBOBJS " in
- *" preadv.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS preadv.$ac_objext"
- ;;
-esac
-
-fi
ac_fn_c_check_decl "$LINENO" "pwritev" "ac_cv_have_decl_pwritev" "#include <sys/uio.h>
"
@@ -16092,16 +16082,6 @@ fi
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_PWRITEV $ac_have_decl
_ACEOF
-if test $ac_have_decl = 1; then :
-
-else
- case " $LIBOBJS " in
- *" pwritev.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS pwritev.$ac_objext"
- ;;
-esac
-
-fi
# This is probably only present on macOS, but may as well check always
diff --git a/configure.ac b/configure.ac
index fed7167e65d..e49de9e4f04 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1816,10 +1816,10 @@ AC_CHECK_DECLS(posix_fadvise, [], [], [#include <fcntl.h>])
AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
AC_CHECK_DECLS([strlcat, strlcpy, strnlen])
-# We can't use AC_REPLACE_FUNCS to replace these functions, because it
+# We can't use AC_CHECK_FUNCS to detect these functions, because it
# won't handle deployment target restrictions on macOS
-AC_CHECK_DECLS([preadv], [], [AC_LIBOBJ(preadv)], [#include <sys/uio.h>])
-AC_CHECK_DECLS([pwritev], [], [AC_LIBOBJ(pwritev)], [#include <sys/uio.h>])
+AC_CHECK_DECLS([preadv], [], [], [#include <sys/uio.h>])
+AC_CHECK_DECLS([pwritev], [], [], [#include <sys/uio.h>])
# This is probably only present on macOS, but may as well check always
AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include <fcntl.h>])
diff --git a/src/include/port/pg_iovec.h b/src/include/port/pg_iovec.h
index 689799c4258..0637d6acaba 100644
--- a/src/include/port/pg_iovec.h
+++ b/src/include/port/pg_iovec.h
@@ -17,6 +17,7 @@
#include <limits.h>
#include <sys/uio.h>
+#include <unistd.h>
#else
@@ -36,20 +37,81 @@ struct iovec
#define PG_IOV_MAX Min(IOV_MAX, 32)
/*
- * Note that pg_preadv and pg_pwritev have a pg_ prefix as a warning that the
- * Windows implementations have the side-effect of changing the file position.
+ * Like preadv(), but with a prefix to remind us of a side-effect: on Windows
+ * this changes the current file position.
*/
-
+static inline ssize_t
+pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+{
#if HAVE_DECL_PREADV
-#define pg_preadv preadv
+ /*
+ * Avoid a small amount of argument copying overhead in the kernel if
+ * there is only one iovec.
+ */
+ if (iovcnt == 1)
+ return pread(fd, iov[0].iov_base, iov[0].iov_len, offset);
+ else
+ return preadv(fd, iov, iovcnt, offset);
#else
-extern ssize_t pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+ ssize_t sum = 0;
+ ssize_t part;
+
+ for (int i = 0; i < iovcnt; ++i)
+ {
+ part = pg_pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
+ if (part < 0)
+ {
+ if (i == 0)
+ return -1;
+ else
+ return sum;
+ }
+ sum += part;
+ offset += part;
+ if (part < iov[i].iov_len)
+ return sum;
+ }
+ return sum;
#endif
+}
+/*
+ * Like pwritev(), but with a prefix to remind us of a side-effect: on Windows
+ * this changes the current file position.
+ */
+static inline ssize_t
+pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+{
#if HAVE_DECL_PWRITEV
-#define pg_pwritev pwritev
+ /*
+ * Avoid a small amount of argument copying overhead in the kernel if
+ * there is only one iovec.
+ */
+ if (iovcnt == 1)
+ return pwrite(fd, iov[0].iov_base, iov[0].iov_len, offset);
+ else
+ return pwritev(fd, iov, iovcnt, offset);
#else
-extern ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+ ssize_t sum = 0;
+ ssize_t part;
+
+ for (int i = 0; i < iovcnt; ++i)
+ {
+ part = pg_pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
+ if (part < 0)
+ {
+ if (i == 0)
+ return -1;
+ else
+ return sum;
+ }
+ sum += part;
+ offset += part;
+ if (part < iov[i].iov_len)
+ return sum;
+ }
+ return sum;
#endif
+}
#endif /* PG_IOVEC_H */
diff --git a/src/port/meson.build b/src/port/meson.build
index a0d0a9583a0..576a48b48c7 100644
--- a/src/port/meson.build
+++ b/src/port/meson.build
@@ -66,8 +66,6 @@ replace_funcs_neg = [
['getpeereid'],
['inet_aton'],
['mkdtemp'],
- ['preadv', 'HAVE_DECL_PREADV'],
- ['pwritev', 'HAVE_DECL_PWRITEV'],
['strlcat'],
['strlcpy'],
['strnlen'],
diff --git a/src/port/preadv.c b/src/port/preadv.c
deleted file mode 100644
index e762283e676..00000000000
--- a/src/port/preadv.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * preadv.c
- * Implementation of preadv(2) for platforms that lack one.
- *
- * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
- *
- * IDENTIFICATION
- * src/port/preadv.c
- *
- *-------------------------------------------------------------------------
- */
-
-
-#include "c.h"
-
-#include <unistd.h>
-
-#include "port/pg_iovec.h"
-
-ssize_t
-pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
-{
- ssize_t sum = 0;
- ssize_t part;
-
- for (int i = 0; i < iovcnt; ++i)
- {
- part = pg_pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
- if (part < 0)
- {
- if (i == 0)
- return -1;
- else
- return sum;
- }
- sum += part;
- offset += part;
- if (part < iov[i].iov_len)
- return sum;
- }
- return sum;
-}
diff --git a/src/port/pwritev.c b/src/port/pwritev.c
deleted file mode 100644
index 519de450374..00000000000
--- a/src/port/pwritev.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * pwritev.c
- * Implementation of pwritev(2) for platforms that lack one.
- *
- * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
- *
- * IDENTIFICATION
- * src/port/pwritev.c
- *
- *-------------------------------------------------------------------------
- */
-
-
-#include "c.h"
-
-#include <unistd.h>
-
-#include "port/pg_iovec.h"
-
-ssize_t
-pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
-{
- ssize_t sum = 0;
- ssize_t part;
-
- for (int i = 0; i < iovcnt; ++i)
- {
- part = pg_pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
- if (part < 0)
- {
- if (i == 0)
- return -1;
- else
- return sum;
- }
- sum += part;
- offset += part;
- if (part < iov[i].iov_len)
- return sum;
- }
- return sum;
-}
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 84f648c174a..d26d1a84e81 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -104,7 +104,7 @@ sub mkvcbuild
inet_net_ntop.c kill.c open.c
snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
dirent.c getopt.c getopt_long.c
- preadv.c pwritev.c pg_bitutils.c
+ pg_bitutils.c
pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c
pqsignal.c mkdtemp.c qsort.c qsort_arg.c bsearch_arg.c quotes.c system.c
strerror.c tar.c