changeset 30256:56ddb6d579cf

fsync: new module * 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.
author Richard W.M. Jones <rjones@redhat.com>
date Wed, 01 Oct 2008 13:54:44 +0100
parents e97324d6f4f9
children 597f6f4a8c4f
files MODULES.html.sh doc/posix-functions/fsync.texi lib/fsync.c lib/unistd.in.h m4/fsync.m4 m4/unistd_h.m4 modules/fsync modules/fsync-tests modules/unistd tests/test-fsync.c
diffstat 10 files changed, 207 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/MODULES.html.sh	Thu Oct 02 08:44:01 2008 +0200
+++ b/MODULES.html.sh	Wed Oct 01 13:54:44 2008 +0100
@@ -2110,6 +2110,7 @@
   func_module freopen
   func_module fseek
   func_module fseeko
+  func_module fsync
   func_module ftell
   func_module ftello
   func_module ftruncate
--- a/doc/posix-functions/fsync.texi	Thu Oct 02 08:44:01 2008 +0200
+++ b/doc/posix-functions/fsync.texi	Wed Oct 01 13:54:44 2008 +0100
@@ -4,15 +4,15 @@
 
 POSIX specification: @url{http://www.opengroup.org/susv3xsh/fsync.html}
 
-Gnulib module: ---
+Gnulib module: fsync
 
 Portability problems fixed by Gnulib:
 @itemize
-@end itemize
-
-Portability problems not fixed by Gnulib:
-@itemize
 @item
 This function is missing on some platforms:
 mingw.
 @end itemize
+
+Portability problems not fixed by Gnulib:
+@itemize
+@end itemize
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/fsync.c	Wed Oct 01 13:54:44 2008 +0100
@@ -0,0 +1,78 @@
+/* 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 */
--- a/lib/unistd.in.h	Thu Oct 02 08:44:01 2008 +0200
+++ b/lib/unistd.in.h	Wed Oct 01 13:54:44 2008 +0100
@@ -140,6 +140,23 @@
 #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	Thu Jan 01 00:00:00 1970 +0000
+++ b/m4/fsync.m4	Wed Oct 01 13:54:44 2008 +0100
@@ -0,0 +1,19 @@
+# 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], [:])
--- a/m4/unistd_h.m4	Thu Oct 02 08:44:01 2008 +0200
+++ b/m4/unistd_h.m4	Wed Oct 01 13:54:44 2008 +0100
@@ -36,6 +36,7 @@
   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])
@@ -48,6 +49,7 @@
   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	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fsync	Wed Oct 01 13:54:44 2008 +0100
@@ -0,0 +1,24 @@
+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	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fsync-tests	Wed Oct 01 13:54:44 2008 +0100
@@ -0,0 +1,10 @@
+Files:
+tests/test-fsync.c
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-fsync
+check_PROGRAMS += test-fsync
--- a/modules/unistd	Thu Oct 02 08:44:01 2008 +0200
+++ b/modules/unistd	Wed Oct 01 13:54:44 2008 +0100
@@ -28,6 +28,7 @@
 	      -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' \
@@ -39,6 +40,7 @@
 	      -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	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-fsync.c	Wed Oct 01 13:54:44 2008 +0100
@@ -0,0 +1,49 @@
+/* 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;
+}