1
0
mirror of https://git.savannah.gnu.org/git/gnulib.git synced 2025-08-08 17:22:05 +03:00

fdatasync: new module

At least libvirt would like to use the lighter-weight fdatasync
on platforms where it is supported, while still guaranteeing full
sync (via the heavy-weight fsync fallback) on all platforms.

I've got an open question to the Austin Group, since the POSIX 2008
wording is self-contradictory (unlike fsync, fdatasync requires
EBADF on non-writable fds, but still mentions that read() errors
must be propagated).  I can see how fsync() would affect atime after
read() while fdatasync() can skip that, explaining why fdatasync()
might have the EBADF requirement, but on the other hand, that prevents
an implementation (like ours) where fdatasync is a straight alias of
fsync.  At any rate, glibc allows fdatasync on read-only fds.

* 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.

Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Eric Blake
2011-09-16 09:59:23 -06:00
parent 9a0a67e426
commit 64da7b6c00
12 changed files with 193 additions and 9 deletions

View File

@@ -1,3 +1,19 @@
2011-09-16 Eric Blake <eblake@redhat.com>
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 <eblake@redhat.com> 2011-09-16 Eric Blake <eblake@redhat.com>
test-fsync: enhance tests test-fsync: enhance tests

View File

@@ -2356,6 +2356,7 @@ func_all_modules ()
func_module fclose func_module fclose
func_module fcntl-h func_module fcntl-h
func_module fcntl func_module fcntl
func_module fdatasync
func_module flock func_module flock
func_module fopen func_module fopen
func_module fprintf-posix func_module fprintf-posix

View File

@@ -4,15 +4,15 @@
POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html} POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html}
Gnulib module: --- Gnulib module: fdatasync
Portability problems fixed by Gnulib: Portability problems fixed by Gnulib:
@itemize @itemize
@end itemize
Portability problems not fixed by Gnulib:
@itemize
@item @item
This function is missing on some platforms: 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. 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 @end itemize
Portability problems not fixed by Gnulib:
@itemize
@end itemize

25
lib/fdatasync.c Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <unistd.h>
int
fdatasync (int fd)
{
return fsync (fd);
}

View File

@@ -484,8 +484,27 @@ _GL_WARN_ON_USE (fchownat, "fchownat is not portable - "
#endif #endif
#if @GNULIB_FSYNC@ #if @GNULIB_FDATASYNC@
/* Synchronize changes to a file. /* Synchronize changes to a file.
Return 0 if successful, otherwise -1 and errno set.
See POSIX:2001 specification
<http://www.opengroup.org/susv3xsh/fdatasync.html>. */
# 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. Return 0 if successful, otherwise -1 and errno set.
See POSIX:2001 specification See POSIX:2001 specification
<http://www.opengroup.org/susv3xsh/fsync.html>. */ <http://www.opengroup.org/susv3xsh/fsync.html>. */

14
m4/fdatasync.m4 Normal file
View File

@@ -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
])

View File

@@ -1,4 +1,4 @@
# unistd_h.m4 serial 58 # unistd_h.m4 serial 59
dnl Copyright (C) 2006-2011 Free Software Foundation, Inc. dnl Copyright (C) 2006-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it, dnl gives unlimited permission to copy and/or distribute it,
@@ -40,7 +40,7 @@ AC_DEFUN([gl_UNISTD_H],
# endif # endif
#endif #endif
]], [chown dup2 dup3 environ euidaccess faccessat fchdir fchownat ]], [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 gethostname getlogin getlogin_r getpagesize getusershell setusershell
endusershell group_member lchown link linkat lseek pipe pipe2 pread pwrite endusershell group_member lchown link linkat lseek pipe pipe2 pread pwrite
readlink readlinkat rmdir sleep symlink symlinkat ttyname_r unlink unlinkat 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_FACCESSAT=0; AC_SUBST([GNULIB_FACCESSAT])
GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR]) GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR])
GNULIB_FCHOWNAT=0; AC_SUBST([GNULIB_FCHOWNAT]) GNULIB_FCHOWNAT=0; AC_SUBST([GNULIB_FCHOWNAT])
GNULIB_FDATASYNC=0; AC_SUBST([GNULIB_FDATASYNC])
GNULIB_FSYNC=0; AC_SUBST([GNULIB_FSYNC]) GNULIB_FSYNC=0; AC_SUBST([GNULIB_FSYNC])
GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE]) GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE])
GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD]) 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_FACCESSAT=1; AC_SUBST([HAVE_FACCESSAT])
HAVE_FCHDIR=1; AC_SUBST([HAVE_FCHDIR]) HAVE_FCHDIR=1; AC_SUBST([HAVE_FCHDIR])
HAVE_FCHOWNAT=1; AC_SUBST([HAVE_FCHOWNAT]) HAVE_FCHOWNAT=1; AC_SUBST([HAVE_FCHOWNAT])
HAVE_FDATASYNC=1; AC_SUBST([HAVE_FDATASYNC])
HAVE_FSYNC=1; AC_SUBST([HAVE_FSYNC]) HAVE_FSYNC=1; AC_SUBST([HAVE_FSYNC])
HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE]) HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE])
HAVE_GETDTABLESIZE=1; AC_SUBST([HAVE_GETDTABLESIZE]) HAVE_GETDTABLESIZE=1; AC_SUBST([HAVE_GETDTABLESIZE])

28
modules/fdatasync Normal file
View File

@@ -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:
<unistd.h>
License:
LGPLv2+
Maintainer:
Eric Blake

13
modules/fdatasync-tests Normal file
View File

@@ -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

View File

@@ -1,5 +1,5 @@
Description: Description:
fsync(2) function: synchronize writes to a file. fsync(2) function: synchronize writes, including metadata, to a file.
Files: Files:
lib/fsync.c lib/fsync.c

View File

@@ -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_FACCESSAT''@/$(GNULIB_FACCESSAT)/g' \
-e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \ -e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \
-e 's/@''GNULIB_FCHOWNAT''@/$(GNULIB_FCHOWNAT)/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_FSYNC''@/$(GNULIB_FSYNC)/g' \
-e 's/@''GNULIB_FTRUNCATE''@/$(GNULIB_FTRUNCATE)/g' \ -e 's/@''GNULIB_FTRUNCATE''@/$(GNULIB_FTRUNCATE)/g' \
-e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/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_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \
-e 's|@''HAVE_FCHDIR''@|$(HAVE_FCHDIR)|g' \ -e 's|@''HAVE_FCHDIR''@|$(HAVE_FCHDIR)|g' \
-e 's|@''HAVE_FCHOWNAT''@|$(HAVE_FCHOWNAT)|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_FSYNC''@|$(HAVE_FSYNC)|g' \
-e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \
-e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \ -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \

64
tests/test-fdatasync.c Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <unistd.h>
#include "signature.h"
SIGNATURE_CHECK (fdatasync, int, (int));
#include <errno.h>
#include <fcntl.h>
#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;
}