diff --git a/ChangeLog b/ChangeLog index e1f97a0c1b..469037c77d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2011-09-16 Eric Blake + + fdatasync: new module + * modules/fsync (Description): Document difference to fdatasync. + * modules/fdatasync: New module. + * m4/fdatasync.m4 (gl_FUNC_FDATASYNC): New file. + * lib/fdatasync.c (fdatasync): Likewise. + * m4/unistd_h.m4 (gl_UNISTD_H, gl_UNISTD_H_DEFAULTS): Set up + defaults. + * modules/unistd (Makefile.am): Set witnesses. + * lib/unistd.in.h (fdatasync): Declare. + * MODULES.html.sh: Document it. + * doc/posix-functions/fdatasync.texi (fdatasync): Likewise. + * modules/fdatasync-tests: New test. + * tests/test-fdatasync.c: Likewise. + 2011-09-16 Eric Blake test-fsync: enhance tests diff --git a/MODULES.html.sh b/MODULES.html.sh index 8785ff2ca2..8273faa56a 100755 --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -2356,6 +2356,7 @@ func_all_modules () func_module fclose func_module fcntl-h func_module fcntl + func_module fdatasync func_module flock func_module fopen func_module fprintf-posix diff --git a/doc/posix-functions/fdatasync.texi b/doc/posix-functions/fdatasync.texi index 88a497c332..8209ecdcfd 100644 --- a/doc/posix-functions/fdatasync.texi +++ b/doc/posix-functions/fdatasync.texi @@ -4,15 +4,15 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html} -Gnulib module: --- +Gnulib module: fdatasync Portability problems fixed by Gnulib: @itemize -@end itemize - -Portability problems not fixed by Gnulib: -@itemize @item This function is missing on some platforms: MacOS X 10.5, FreeBSD 6.0, OpenBSD 3.8, Minix 3.1.8, IRIX 5.3, Solaris 2.4, mingw, MSVC 9, Interix 3.5, BeOS. @end itemize + +Portability problems not fixed by Gnulib: +@itemize +@end itemize diff --git a/lib/fdatasync.c b/lib/fdatasync.c new file mode 100644 index 0000000000..54c10fd91a --- /dev/null +++ b/lib/fdatasync.c @@ -0,0 +1,25 @@ +/* Emulate fdatasync on platforms that lack it. + + Copyright (C) 2011 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser 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 +#include + +int +fdatasync (int fd) +{ + return fsync (fd); +} diff --git a/lib/unistd.in.h b/lib/unistd.in.h index c1cfb54264..3ad166c677 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -484,8 +484,27 @@ _GL_WARN_ON_USE (fchownat, "fchownat is not portable - " #endif -#if @GNULIB_FSYNC@ +#if @GNULIB_FDATASYNC@ /* Synchronize changes to a file. + Return 0 if successful, otherwise -1 and errno set. + See POSIX:2001 specification + . */ +# if !@HAVE_FDATASYNC@ +_GL_FUNCDECL_SYS (fdatasync, int, (int fd)); +# endif +_GL_CXXALIAS_SYS (fdatasync, int, (int fd)); +_GL_CXXALIASWARN (fdatasync); +#elif defined GNULIB_POSIXCHECK +# undef fdatasync +# if HAVE_RAW_DECL_FDATASYNC +_GL_WARN_ON_USE (fdatasync, "fdatasync is unportable - " + "use gnulib module fdatasync for portability"); +# endif +#endif + + +#if @GNULIB_FSYNC@ +/* Synchronize changes, including metadata, to a file. Return 0 if successful, otherwise -1 and errno set. See POSIX:2001 specification . */ diff --git a/m4/fdatasync.m4 b/m4/fdatasync.m4 new file mode 100644 index 0000000000..8eceeb547b --- /dev/null +++ b/m4/fdatasync.m4 @@ -0,0 +1,14 @@ +# fdatasync.m4 serial 1 +dnl Copyright (C) 2008-2011 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_FDATASYNC], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([fdatasync]) + if test $ac_cv_func_fdatasync = no; then + HAVE_FDATASYNC=0 + fi +]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index 33897ae927..29f3947b5e 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -1,4 +1,4 @@ -# unistd_h.m4 serial 58 +# unistd_h.m4 serial 59 dnl Copyright (C) 2006-2011 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -40,7 +40,7 @@ AC_DEFUN([gl_UNISTD_H], # endif #endif ]], [chown dup2 dup3 environ euidaccess faccessat fchdir fchownat - fsync ftruncate getcwd getdomainname getdtablesize getgroups + fdatasync fsync ftruncate getcwd getdomainname getdtablesize getgroups gethostname getlogin getlogin_r getpagesize getusershell setusershell endusershell group_member lchown link linkat lseek pipe pipe2 pread pwrite readlink readlinkat rmdir sleep symlink symlinkat ttyname_r unlink unlinkat @@ -67,6 +67,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], GNULIB_FACCESSAT=0; AC_SUBST([GNULIB_FACCESSAT]) GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR]) GNULIB_FCHOWNAT=0; AC_SUBST([GNULIB_FCHOWNAT]) + GNULIB_FDATASYNC=0; AC_SUBST([GNULIB_FDATASYNC]) GNULIB_FSYNC=0; AC_SUBST([GNULIB_FSYNC]) GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE]) GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD]) @@ -110,6 +111,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], HAVE_FACCESSAT=1; AC_SUBST([HAVE_FACCESSAT]) HAVE_FCHDIR=1; AC_SUBST([HAVE_FCHDIR]) HAVE_FCHOWNAT=1; AC_SUBST([HAVE_FCHOWNAT]) + HAVE_FDATASYNC=1; AC_SUBST([HAVE_FDATASYNC]) HAVE_FSYNC=1; AC_SUBST([HAVE_FSYNC]) HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE]) HAVE_GETDTABLESIZE=1; AC_SUBST([HAVE_GETDTABLESIZE]) diff --git a/modules/fdatasync b/modules/fdatasync new file mode 100644 index 0000000000..7b78a800b9 --- /dev/null +++ b/modules/fdatasync @@ -0,0 +1,28 @@ +Description: +fdatasync(2) function: synchronize writes to a file. + +Files: +lib/fdatasync.c +m4/fdatasync.m4 + +Depends-on: +fsync +unistd + +configure.ac: +gl_FUNC_FDATASYNC +if test $HAVE_FDATASYNC = 0; then + AC_LIBOBJ([fdatasync]) +fi +gl_UNISTD_MODULE_INDICATOR([fdatasync]) + +Makefile.am: + +Include: + + +License: +LGPLv2+ + +Maintainer: +Eric Blake diff --git a/modules/fdatasync-tests b/modules/fdatasync-tests new file mode 100644 index 0000000000..9afd058deb --- /dev/null +++ b/modules/fdatasync-tests @@ -0,0 +1,13 @@ +Files: +tests/test-fdatasync.c +tests/signature.h +tests/macros.h + +Depends-on: +errno + +configure.ac: + +Makefile.am: +TESTS += test-fdatasync +check_PROGRAMS += test-fdatasync diff --git a/modules/fsync b/modules/fsync index 0092226ca8..0f5b3fc793 100644 --- a/modules/fsync +++ b/modules/fsync @@ -1,5 +1,5 @@ Description: -fsync(2) function: synchronize writes to a file. +fsync(2) function: synchronize writes, including metadata, to a file. Files: lib/fsync.c diff --git a/modules/unistd b/modules/unistd index d6642a7f0a..f843a2ff36 100644 --- a/modules/unistd +++ b/modules/unistd @@ -39,6 +39,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_FACCESSAT''@/$(GNULIB_FACCESSAT)/g' \ -e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \ -e 's/@''GNULIB_FCHOWNAT''@/$(GNULIB_FCHOWNAT)/g' \ + -e 's/@''GNULIB_FDATASYNC''@/$(GNULIB_FDATASYNC)/g' \ -e 's/@''GNULIB_FSYNC''@/$(GNULIB_FSYNC)/g' \ -e 's/@''GNULIB_FTRUNCATE''@/$(GNULIB_FTRUNCATE)/g' \ -e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/g' \ @@ -82,6 +83,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''HAVE_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \ -e 's|@''HAVE_FCHDIR''@|$(HAVE_FCHDIR)|g' \ -e 's|@''HAVE_FCHOWNAT''@|$(HAVE_FCHOWNAT)|g' \ + -e 's|@''HAVE_FDATASYNC''@|$(HAVE_FDATASYNC)|g' \ -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \ -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \ diff --git a/tests/test-fdatasync.c b/tests/test-fdatasync.c new file mode 100644 index 0000000000..d23e6db388 --- /dev/null +++ b/tests/test-fdatasync.c @@ -0,0 +1,64 @@ +/* Test of fdatasync() function. + Copyright (C) 2008-2011 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 + +#include + +#include "signature.h" +SIGNATURE_CHECK (fdatasync, int, (int)); + +#include +#include + +#include "macros.h" + +int +main (void) +{ + int fd; + const char *file = "test-fdatasync.txt"; + + if (fdatasync (STDOUT_FILENO) != 0) + { + ASSERT (errno == EINVAL /* POSIX */ + || errno == ENOTSUP /* seen on MacOS X 10.5 */ + || errno == EBADF /* seen on AIX 7.1 */ + ); + } + errno = 0; + ASSERT (fdatasync (-1) == -1); + ASSERT (errno == EBADF); + fd = open (file, O_WRONLY|O_CREAT|O_TRUNC, 0644); + ASSERT (0 <= fd); + ASSERT (write (fd, "hello", 5) == 5); + ASSERT (fdatasync (fd) == 0); + ASSERT (close (fd) == 0); +#if 0 + /* POSIX is self-contradictory on whether fdatasync must fail on + read-only file descriptors. Glibc allows it, as does our + implementation if fsync allows it. */ + fd = open (file, O_RDONLY); + ASSERT (0 <= fd); + errno = 0; + ASSERT (fdatasync (fd) == -1); + ASSERT (errno == EBADF); + ASSERT (close (fd) == 0); +#endif + ASSERT (unlink (file) == 0); + + return 0; +}