Index: configure.in =================================================================== RCS file: /projects/cvsroot/pgsql/configure.in,v retrieving revision 1.427 diff -u -r1.427 configure.in --- configure.in 5 Oct 2005 17:11:45 -0000 1.427 +++ configure.in 8 Oct 2005 13:48:23 -0000 @@ -817,6 +817,7 @@ PGAC_VAR_INT_TIMEZONE AC_FUNC_ACCEPT_ARGTYPES PGAC_FUNC_GETTIMEOFDAY_1ARG +PGAC_FUNC_REAL_PREAD AC_CHECK_FUNCS([cbrt dlopen fcvt fdatasync getpeereid memmove poll pstat readlink setproctitle setsid sigprocmask symlink sysconf towlower utime utimes waitpid wcstombs]) Index: config/c-library.m4 =================================================================== RCS file: /projects/cvsroot/pgsql/config/c-library.m4,v retrieving revision 1.31 diff -u -r1.31 c-library.m4 --- config/c-library.m4 24 Feb 2005 01:34:45 -0000 1.31 +++ config/c-library.m4 8 Oct 2005 13:48:23 -0000 @@ -297,3 +297,43 @@ ])dnl AC_CACHE_VAL AC_MSG_RESULT([$pgac_cv_printf_arg_control]) ])# PGAC_FUNC_PRINTF_ARG_CONTROL + +# PGAC_FUNC_REAL_PREAD +# ------------------------------------------ +# Determine if pread exists and that it is not emulated +# +AC_DEFUN([PGAC_FUNC_REAL_PREAD], +[AC_MSG_CHECKING([for verified non-emulated pread]) +AC_CACHE_VAL(pgac_cv_real_pread, +[AC_TRY_RUN([#include +#include +#include + +#if !defined(linux) || !defined(__GLIBC__) +int main() { return 1; } /* Don't actually know... */ +#else +/* Avoid conflict with system header */ +#define pread64 pg_pread +static inline _syscall5(int,pread64,int,__fd, void *,__buf, size_t, __nbytes,__off_t, __offlow, __off_t, __offhigh); + +int main() +{ + char buffer[10]; + + int err = pread64(-1,buffer,1,1,0); + + if( errno == EBADF ) + return 0; + + return 1; +} +#endif +], +[pgac_cv_real_pread=yes], +[pgac_cv_real_pread=no], +[pgac_cv_real_pread=cross]) +])dnl AC_CACHE_VAL +AC_MSG_RESULT([$pgac_cv_real_pread]) +if test x"$pgac_cv_real_pread" = xyes ; then + AC_DEFINE(HAVE_REAL_PREAD, 1, [Define to 1 if you have a pread known not to be emulated.]) +fi])# PGAC_FUNC_REAL_PREAD Index: src/backend/storage/file/fd.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/storage/file/fd.c,v retrieving revision 1.120 diff -u -r1.120 fd.c --- src/backend/storage/file/fd.c 8 Aug 2005 03:11:49 -0000 1.120 +++ src/backend/storage/file/fd.c 8 Oct 2005 13:48:25 -0000 @@ -531,9 +531,11 @@ /* delete the vfd record from the LRU ring */ Delete(file); +#ifndef HAVE_REAL_PREAD /* save the seek position */ vfdP->seekPos = (long) lseek(vfdP->fd, 0L, SEEK_CUR); Assert(vfdP->seekPos != -1L); +#endif /* close the file */ if (close(vfdP->fd)) @@ -604,6 +606,7 @@ ++nfile; } +#ifndef HAVE_REAL_PREAD /* seek to the right position */ if (vfdP->seekPos != 0L) { @@ -612,6 +615,7 @@ returnValue = (long) lseek(vfdP->fd, vfdP->seekPos, SEEK_SET); Assert(returnValue != -1L); } +#endif } /* @@ -1010,8 +1014,15 @@ returnCode = FileAccess(file); if (returnCode < 0) return returnCode; + +#ifdef HAVE_REAL_PREAD + if( VfdCache[file].seekPos == FileUnknownPos ) + ereport( ERROR, (errmsg("read() with unknown position")) ); + returnCode = pread(VfdCache[file].fd, buffer, amount, VfdCache[file].seekPos ); +#else returnCode = read(VfdCache[file].fd, buffer, amount); +#endif if (returnCode > 0) VfdCache[file].seekPos += returnCode; else @@ -1036,8 +1047,14 @@ return returnCode; errno = 0; +#ifdef HAVE_REAL_PREAD + if( VfdCache[file].seekPos == FileUnknownPos ) + ereport( ERROR, (errmsg("write() with unknown position")) ); + + returnCode = pwrite(VfdCache[file].fd, buffer, amount, VfdCache[file].seekPos ); +#else returnCode = write(VfdCache[file].fd, buffer, amount); - +#endif /* if write didn't set errno, assume problem is no disk space */ if (returnCode != amount && errno == 0) errno = ENOSPC; @@ -1078,8 +1095,11 @@ file, VfdCache[file].fileName, VfdCache[file].seekPos, offset, whence)); +/* Yes, not pretty. Fact is, with pread we always track the position ourselves */ +#ifndef HAVE_REAL_PREAD if (FileIsNotOpen(file)) { +#endif switch (whence) { case SEEK_SET: @@ -1101,6 +1121,7 @@ elog(ERROR, "invalid whence: %d", whence); break; } +#ifndef HAVE_REAL_PREAD } else { @@ -1127,6 +1148,7 @@ break; } } +#endif return VfdCache[file].seekPos; }