Skip to content

Commit 3fd2a79

Browse files
committed
Provide pg_pread() and pg_pwrite() for random I/O.
Forward to POSIX pread() and pwrite(), or emulate them if unavailable. The emulation is not perfect as the file position is changed, so we'll put pg_ prefixes on the names to minimize the risk of confusion in future patches that might inadvertently try to mix pread() and read() on the same file descriptor. Author: Thomas Munro Reviewed-by: Tom Lane, Jesper Pedersen Discussion: https://postgr.es/m/CAEepm=02rapCpPR3ZGF2vW=SBHSdFYO_bz_f-wwWJonmA3APgw@mail.gmail.com
1 parent b43df56 commit 3fd2a79

File tree

8 files changed

+168
-0
lines changed

8 files changed

+168
-0
lines changed

configure

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15539,6 +15539,32 @@ esac
1553915539

1554015540
fi
1554115541

15542+
ac_fn_c_check_func "$LINENO" "pread" "ac_cv_func_pread"
15543+
if test "x$ac_cv_func_pread" = xyes; then :
15544+
$as_echo "#define HAVE_PREAD 1" >>confdefs.h
15545+
15546+
else
15547+
case " $LIBOBJS " in
15548+
*" pread.$ac_objext "* ) ;;
15549+
*) LIBOBJS="$LIBOBJS pread.$ac_objext"
15550+
;;
15551+
esac
15552+
15553+
fi
15554+
15555+
ac_fn_c_check_func "$LINENO" "pwrite" "ac_cv_func_pwrite"
15556+
if test "x$ac_cv_func_pwrite" = xyes; then :
15557+
$as_echo "#define HAVE_PWRITE 1" >>confdefs.h
15558+
15559+
else
15560+
case " $LIBOBJS " in
15561+
*" pwrite.$ac_objext "* ) ;;
15562+
*) LIBOBJS="$LIBOBJS pwrite.$ac_objext"
15563+
;;
15564+
esac
15565+
15566+
fi
15567+
1554215568
ac_fn_c_check_func "$LINENO" "random" "ac_cv_func_random"
1554315569
if test "x$ac_cv_func_random" = xyes; then :
1554415570
$as_echo "#define HAVE_RANDOM 1" >>confdefs.h

configure.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,6 +1698,8 @@ AC_REPLACE_FUNCS(m4_normalize([
16981698
getrusage
16991699
inet_aton
17001700
mkdtemp
1701+
pread
1702+
pwrite
17011703
random
17021704
rint
17031705
srandom

src/include/pg_config.h.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,9 @@
438438
/* Define to 1 if you have the `ppoll' function. */
439439
#undef HAVE_PPOLL
440440

441+
/* Define to 1 if you have the `pread' function. */
442+
#undef HAVE_PREAD
443+
441444
/* Define to 1 if you have the `pstat' function. */
442445
#undef HAVE_PSTAT
443446

@@ -453,6 +456,9 @@
453456
/* Have PTHREAD_PRIO_INHERIT. */
454457
#undef HAVE_PTHREAD_PRIO_INHERIT
455458

459+
/* Define to 1 if you have the `pwrite' function. */
460+
#undef HAVE_PWRITE
461+
456462
/* Define to 1 if you have the `random' function. */
457463
#undef HAVE_RANDOM
458464

src/include/pg_config.h.win32

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,18 @@
322322
/* Define to 1 if you have the `ppoll' function. */
323323
/* #undef HAVE_PPOLL */
324324

325+
/* Define to 1 if you have the `pread' function. */
326+
/* #undef HAVE_PREAD */
327+
325328
/* Define to 1 if you have the `pstat' function. */
326329
/* #undef HAVE_PSTAT */
327330

328331
/* Define to 1 if the PS_STRINGS thing exists. */
329332
/* #undef HAVE_PS_STRINGS */
330333

334+
/* Define to 1 if you have the `pwrite' function. */
335+
/* #undef HAVE_PWRITE */
336+
331337
/* Define to 1 if you have the `random' function. */
332338
/* #undef HAVE_RANDOM */
333339

src/include/port.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,23 @@ extern double rint(double x);
392392
extern int inet_aton(const char *cp, struct in_addr *addr);
393393
#endif
394394

395+
/*
396+
* Windows and older Unix don't have pread(2) and pwrite(2). We have
397+
* replacement functions, but they have slightly different semantics so we'll
398+
* use a name with a pg_ prefix to avoid confusion.
399+
*/
400+
#ifdef HAVE_PREAD
401+
#define pg_pread pread
402+
#else
403+
extern ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset);
404+
#endif
405+
406+
#ifdef HAVE_PWRITE
407+
#define pg_pwrite pwrite
408+
#else
409+
extern ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
410+
#endif
411+
395412
#if !HAVE_DECL_STRLCAT
396413
extern size_t strlcat(char *dst, const char *src, size_t siz);
397414
#endif

src/port/pread.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* pread.c
4+
* Implementation of pread(2) for platforms that lack one.
5+
*
6+
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
7+
*
8+
* IDENTIFICATION
9+
* src/port/pread.c
10+
*
11+
* Note that this implementation changes the current file position, unlike
12+
* the POSIX function, so we use the name pg_pread().
13+
*
14+
*-------------------------------------------------------------------------
15+
*/
16+
17+
18+
#include "postgres.h"
19+
20+
#ifdef WIN32
21+
#include <windows.h>
22+
#else
23+
#include <unistd.h>
24+
#endif
25+
26+
ssize_t
27+
pg_pread(int fd, void *buf, size_t size, off_t offset)
28+
{
29+
#ifdef WIN32
30+
OVERLAPPED overlapped = {0};
31+
HANDLE handle;
32+
DWORD result;
33+
34+
handle = (HANDLE) _get_osfhandle(fd);
35+
if (handle == INVALID_HANDLE_VALUE)
36+
{
37+
errno = EBADF;
38+
return -1;
39+
}
40+
41+
overlapped.Offset = offset;
42+
if (!ReadFile(handle, buf, size, &result, &overlapped))
43+
{
44+
_dosmaperr(GetLastError());
45+
return -1;
46+
}
47+
48+
return result;
49+
#else
50+
if (lseek(fd, offset, SEEK_SET) < 0)
51+
return -1;
52+
53+
return read(fd, buf, size);
54+
#endif
55+
}

src/port/pwrite.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* pwrite.c
4+
* Implementation of pwrite(2) for platforms that lack one.
5+
*
6+
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
7+
*
8+
* IDENTIFICATION
9+
* src/port/pwrite.c
10+
*
11+
* Note that this implementation changes the current file position, unlike
12+
* the POSIX function, so we use the name pg_write().
13+
*
14+
*-------------------------------------------------------------------------
15+
*/
16+
17+
18+
#include "postgres.h"
19+
20+
#ifdef WIN32
21+
#include <windows.h>
22+
#else
23+
#include <unistd.h>
24+
#endif
25+
26+
ssize_t
27+
pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
28+
{
29+
#ifdef WIN32
30+
OVERLAPPED overlapped = {0};
31+
HANDLE handle;
32+
DWORD result;
33+
34+
handle = (HANDLE) _get_osfhandle(fd);
35+
if (handle == INVALID_HANDLE_VALUE)
36+
{
37+
errno = EBADF;
38+
return -1;
39+
}
40+
41+
overlapped.Offset = offset;
42+
if (!WriteFile(handle, buf, size, &result, &overlapped))
43+
{
44+
_dosmaperr(GetLastError());
45+
return -1;
46+
}
47+
48+
return result;
49+
#else
50+
if (lseek(fd, offset, SEEK_SET) < 0)
51+
return -1;
52+
53+
return write(fd, buf, size);
54+
#endif
55+
}

src/tools/msvc/Mkvcbuild.pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ sub mkvcbuild
9797
srandom.c getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
9898
erand48.c snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
9999
dirent.c dlopen.c getopt.c getopt_long.c
100+
pread.c pwrite.c
100101
pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c
101102
pqsignal.c mkdtemp.c qsort.c qsort_arg.c quotes.c system.c
102103
sprompt.c strerror.c tar.c thread.c

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy