From f84e1a91fb3c43ba06567cbaeaf641135170d35a Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Wed, 25 Nov 2009 14:33:30 +0100 Subject: [PATCH] pread: new module * modules/pread: New file. * lib/pread.c (pread): New file. * m4/pread.m4: Likewise. * lib/unistd.in.h (pread): Define/declare. * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Define defaults. * modules/unistd (Makefile.am): Substitute witnesses. * doc/posix-functions/pread.texi (pread): Update. * MODULES.html.sh: Add pread. --- ChangeLog | 11 ++++++++ MODULES.html.sh | 1 + doc/posix-functions/pread.texi | 6 ++-- lib/pread.c | 64 ++++++++++++++++++++++++++++++++++++++++++ lib/unistd.in.h | 20 +++++++++++++ m4/pread.m4 | 15 ++++++++++ m4/unistd_h.m4 | 3 ++ modules/pread | 24 ++++++++++++++++ modules/unistd | 3 ++ 9 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 lib/pread.c create mode 100644 m4/pread.m4 create mode 100644 modules/pread diff --git a/ChangeLog b/ChangeLog index c0ce45b88..c255af034 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2009-11-25 Jim Meyering + pread: new module + * modules/pread: New file. + * lib/unistd.in.h (pread): Define/declare. + * lib/pread.c (pread): New file. + * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Define defaults. + * modules/unistd (Makefile.am): Substitute witnesses. + * doc/posix-functions/pread.texi (pread): Update. + * MODULES.html.sh: Add pread. + +2009-11-25 Jim Meyering + tests/init.sh: new file to be used via most *.sh tests * tests/init.sh: New file. diff --git a/MODULES.html.sh b/MODULES.html.sh index 7fc55dd8a..9d5664a2b 100755 --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -1345,6 +1345,7 @@ h_errno index makecontext mktemp +pread pthread_attr_getstackaddr pthread_attr_setstackaddr rindex diff --git a/doc/posix-functions/pread.texi b/doc/posix-functions/pread.texi index d1d6403a8..a11e36eac 100644 --- a/doc/posix-functions/pread.texi +++ b/doc/posix-functions/pread.texi @@ -8,11 +8,11 @@ Gnulib module: --- Portability problems fixed by Gnulib: @itemize +@item +This function is missing on some platforms: +mingw, BeOS. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on some platforms: -mingw, BeOS. @end itemize diff --git a/lib/pread.c b/lib/pread.c new file mode 100644 index 000000000..632b91497 --- /dev/null +++ b/lib/pread.c @@ -0,0 +1,64 @@ +/* replacement pread function + Copyright (C) 2009 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include + +#define __libc_lseek(f,o,w) lseek (f, o, w) +#define __set_errno(Val) errno = (Val) + +/* pread substitute for systems that the function, such as mingw32 and BeOS. */ +/* The following is identical to the function from glibc's + sysdeps/posix/pread.c */ + +/* Note: This implementation of pread is not multithread-safe. */ + +ssize_t +pread (int fd, void *buf, size_t nbyte, off_t offset) +{ + /* Since we must not change the file pointer preserve the value so that + we can restore it later. */ + int save_errno; + ssize_t result; + off_t old_offset = __libc_lseek (fd, 0, SEEK_CUR); + if (old_offset == (off_t) -1) + return -1; + + /* Set to wanted position. */ + if (__libc_lseek (fd, offset, SEEK_SET) == (off_t) -1) + return -1; + + /* Write out the data. */ + result = __libc_read (fd, buf, nbyte); + + /* Now we have to restore the position. If this fails we have to + return this as an error. But if the writing also failed we + return this error. */ + save_errno = errno; + if (__libc_lseek (fd, old_offset, SEEK_SET) == (off_t) -1) + { + if (result == -1) + __set_errno (save_errno); + return -1; + } + __set_errno (save_errno); + + return result; +} diff --git a/lib/unistd.in.h b/lib/unistd.in.h index 9a9a67111..13d1bbac9 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -664,6 +664,26 @@ extern int pipe2 (int fd[2], int flags); #endif +#if @GNULIB_PREAD@ +# if @REPLACE_PREAD@ +# define pread rpl_pread +# endif +/* Read at most BUFSIZE bytes from FD into BUF, starting at OFFSET. + Return the number of bytes placed into BUF if successful, otherwise + set errno and return -1. 0 indicates EOF. See the POSIX:2001 + specification . */ +# if !@HAVE_PREAD@ || @REPLACE_PREAD@ + extern ssize_t pread (int fd, char *buf, size_t bufsize, off_t offset); +# endif +#elif defined GNULIB_POSIXCHECK +# undef pread +# define pread(f,b,s,o) \ + (GL_LINK_WARNING ("pread is unportable - " \ + "use gnulib module pread for portability"), \ + pread (f, b, s, o)) +#endif + + #if @GNULIB_READLINK@ # if @REPLACE_READLINK@ # define readlink rpl_readlink diff --git a/m4/pread.m4 b/m4/pread.m4 new file mode 100644 index 000000000..c281362df --- /dev/null +++ b/m4/pread.m4 @@ -0,0 +1,15 @@ +# pread.m4 serial 1 +dnl Copyright (C) 2009 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_PREAD], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([pread]) + if test $ac_cv_func_pread = no; then + HAVE_PREAD=0 + AC_LIBOBJ([pread]) + fi +]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index 0a5b5d5a7..cb50d50e0 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -56,6 +56,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], GNULIB_LINKAT=0; AC_SUBST([GNULIB_LINKAT]) GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK]) GNULIB_PIPE2=0; AC_SUBST([GNULIB_PIPE2]) + GNULIB_PREAD=0; AC_SUBST([GNULIB_PREAD]) GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK]) GNULIB_READLINKAT=0; AC_SUBST([GNULIB_READLINKAT]) GNULIB_RMDIR=0; AC_SUBST([GNULIB_RMDIR]) @@ -87,6 +88,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], HAVE_LINK=1; AC_SUBST([HAVE_LINK]) HAVE_LINKAT=1; AC_SUBST([HAVE_LINKAT]) HAVE_PIPE2=1; AC_SUBST([HAVE_PIPE2]) + HAVE_PREAD=1; AC_SUBST([HAVE_PREAD]) HAVE_READLINK=1; AC_SUBST([HAVE_READLINK]) HAVE_READLINKAT=1; AC_SUBST([HAVE_READLINKAT]) HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP]) @@ -111,6 +113,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], REPLACE_LINK=0; AC_SUBST([REPLACE_LINK]) REPLACE_LINKAT=0; AC_SUBST([REPLACE_LINKAT]) REPLACE_LSEEK=0; AC_SUBST([REPLACE_LSEEK]) + REPLACE_PREAD=0; AC_SUBST([REPLACE_PREAD]) REPLACE_READLINK=0; AC_SUBST([REPLACE_READLINK]) REPLACE_RMDIR=0; AC_SUBST([REPLACE_RMDIR]) REPLACE_SLEEP=0; AC_SUBST([REPLACE_SLEEP]) diff --git a/modules/pread b/modules/pread new file mode 100644 index 000000000..06039e64d --- /dev/null +++ b/modules/pread @@ -0,0 +1,24 @@ +Description: +pread() function: read without changing file offset + +Files: +lib/pread.c +m4/pread.m4 + +Depends-on: +unistd + +configure.ac: +gl_FUNC_PREAD +gl_UNISTD_MODULE_INDICATOR([pread]) + +Makefile.am: + +Include: + + +License: +LGPLv2+ + +Maintainer: +Jim Meyering diff --git a/modules/unistd b/modules/unistd index 1282e5380..7a5500101 100644 --- a/modules/unistd +++ b/modules/unistd @@ -49,6 +49,7 @@ unistd.h: unistd.in.h -e 's|@''GNULIB_LINKAT''@|$(GNULIB_LINKAT)|g' \ -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \ -e 's|@''GNULIB_PIPE2''@|$(GNULIB_PIPE2)|g' \ + -e 's|@''GNULIB_PREAD''@|$(GNULIB_PREAD)|g' \ -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \ -e 's|@''GNULIB_READLINKAT''@|$(GNULIB_READLINKAT)|g' \ -e 's|@''GNULIB_RMDIR''@|$(GNULIB_RMDIR)|g' \ @@ -79,6 +80,7 @@ unistd.h: unistd.in.h -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \ -e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|g' \ -e 's|@''HAVE_PIPE2''@|$(HAVE_PIPE2)|g' \ + -e 's|@''HAVE_PREAD''@|$(HAVE_PREAD)|g' \ -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \ -e 's|@''HAVE_READLINKAT''@|$(HAVE_READLINKAT)|g' \ -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \ @@ -103,6 +105,7 @@ unistd.h: unistd.in.h -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \ -e 's|@''REPLACE_LINKAT''@|$(REPLACE_LINKAT)|g' \ -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \ + -e 's|@''REPLACE_PREAD''@|$(REPLACE_PREAD)|g' \ -e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \ -e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \ -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \ -- 2.11.0