* lib/fsync.c: New file.
* m4/fsync.m4: New file.
* modules/fsync: New file.
* modules/fsync-tests: New file.
* tests/test-fsync.c: New file.
* modules/unistd: Substitute GNULIB_FSYNC and HAVE_FSYNC.
* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Define and AC_SUBST
both GNULIB_FSYNC and HAVE_FSYNC.
* lib/unistd.in.h (@GNULIB_FSYNC@): Add a block for fsync.
* MODULES.html.sh (posix_functions): Add fsync.
* doc/posix-functions/fsync.texi: Update.
func_module freopen
func_module fseek
func_module fseeko
+ func_module fsync
func_module ftell
func_module ftello
func_module ftruncate
POSIX specification: @url{http://www.opengroup.org/susv3xsh/fsync.html}
-Gnulib module: ---
+Gnulib module: fsync
Portability problems fixed by Gnulib:
@itemize
+@item
+This function is missing on some platforms:
+mingw.
@end itemize
Portability problems not fixed by Gnulib:
@itemize
-@item
-This function is missing on some platforms:
-mingw.
@end itemize
--- /dev/null
+/* Emulate fsync on platforms that lack it, primarily Windows and
+ cross-compilers like MinGW.
+
+ This is derived from sqlite3 sources.
+ http://www.sqlite.org/cvstrac/rlog?f=sqlite/src/os_win.c
+ http://www.sqlite.org/copyright.html
+
+ Written by Richard W.M. Jones <rjones.at.redhat.com>
+
+ Copyright (C) 2008 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>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+/* _get_osfhandle */
+#include <io.h>
+
+/* FlushFileBuffers */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <errno.h>
+
+int
+fsync (int fd)
+{
+ HANDLE h = (HANDLE) _get_osfhandle (fd);
+ DWORD err;
+
+ if (h == INVALID_HANDLE_VALUE)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (!FlushFileBuffers (h))
+ {
+ /* Translate some Windows errors into rough approximations of Unix
+ * errors. MSDN is useless as usual - in this case it doesn't
+ * document the full range of errors.
+ */
+ err = GetLastError ();
+ switch (err)
+ {
+ /* eg. Trying to fsync a tty. */
+ case ERROR_INVALID_HANDLE:
+ errno = EINVAL;
+ break;
+
+ default:
+ errno = EIO;
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
+#else /* !Windows */
+
+#error "This platform lacks fsync function, and Gnulib doesn't provide a replacement. This is a bug in Gnulib."
+
+#endif /* !Windows */
#endif
+#if @GNULIB_FSYNC@
+/* Synchronize changes to a file.
+ Return 0 if successful, otherwise -1 and errno set.
+ See POSIX:2001 specification
+ <http://www.opengroup.org/susv3xsh/fsync.html>. */
+# if !@HAVE_FSYNC@
+extern int fsync (int fd);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef fsync
+# define fsync(fd) \
+ (GL_LINK_WARNING ("fsync is unportable - " \
+ "use gnulib module fsync for portability"), \
+ fsync (fd))
+#endif
+
+
#if @GNULIB_FTRUNCATE@
# if !@HAVE_FTRUNCATE@
/* Change the size of the file to which FD is opened to become equal to LENGTH.
--- /dev/null
+# fsync.m4 serial 1
+dnl Copyright (C) 2008 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_FSYNC],
+[
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+ AC_CHECK_FUNCS_ONCE([fsync])
+ if test $ac_cv_func_fsync = no; then
+ HAVE_FSYNC=0
+ AC_LIBOBJ([fsync])
+ gl_PREREQ_FSYNC
+ fi
+])
+
+# Prerequisites of lib/fsync.c.
+AC_DEFUN([gl_PREREQ_FSYNC], [:])
GNULIB_DUP2=0; AC_SUBST([GNULIB_DUP2])
GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON])
GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR])
+ GNULIB_FSYNC=0; AC_SUBST([GNULIB_FSYNC])
GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE])
GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD])
GNULIB_GETLOGIN_R=0; AC_SUBST([GNULIB_GETLOGIN_R])
GNULIB_WRITE=0; AC_SUBST([GNULIB_WRITE])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_DUP2=1; AC_SUBST([HAVE_DUP2])
+ HAVE_FSYNC=1; AC_SUBST([HAVE_FSYNC])
HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE])
HAVE_GETPAGESIZE=1; AC_SUBST([HAVE_GETPAGESIZE])
HAVE_READLINK=1; AC_SUBST([HAVE_READLINK])
--- /dev/null
+Description:
+fsync(2) function: synchronize writes to a file.
+
+Files:
+lib/fsync.c
+m4/fsync.m4
+
+Depends-on:
+unistd
+
+configure.ac:
+gl_FUNC_FSYNC
+gl_UNISTD_MODULE_INDICATOR([fsync])
+
+Makefile.am:
+
+Include:
+<unistd.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+Richard W.M. Jones, Jim Meyering
--- /dev/null
+Files:
+tests/test-fsync.c
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-fsync
+check_PROGRAMS += test-fsync
-e 's|@''GNULIB_DUP2''@|$(GNULIB_DUP2)|g' \
-e 's|@''GNULIB_ENVIRON''@|$(GNULIB_ENVIRON)|g' \
-e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \
+ -e 's|@''GNULIB_FSYNC''@|$(GNULIB_FSYNC)|g' \
-e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \
-e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \
-e 's|@''GNULIB_GETLOGIN_R''@|$(GNULIB_GETLOGIN_R)|g' \
-e 's|@''GNULIB_UNISTD_H_SIGPIPE''@|$(GNULIB_UNISTD_H_SIGPIPE)|g' \
-e 's|@''GNULIB_WRITE''@|$(GNULIB_WRITE)|g' \
-e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \
+ -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \
-e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \
-e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \
-e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \
--- /dev/null
+/* Test of fsync() function.
+ Copyright (C) 2008 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 2 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 <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#define ASSERT(expr) \
+ do \
+ { \
+ if (!(expr)) \
+ { \
+ fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
+ fflush (stderr); \
+ abort (); \
+ } \
+ } \
+ while (0)
+
+int
+main ()
+{
+ int fd;
+ const char *file = "test-fsync.txt";
+
+ ASSERT (fsync (0) != 0);
+ fd = open (file, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ ASSERT (0 <= fd);
+ ASSERT (write (fd, "hello", 5) == 5);
+ ASSERT (fsync (fd) == 0);
+ ASSERT (close (fd) == 0);
+ ASSERT (unlink (file) == 0);
+
+ return 0;
+}