>From c518eebf6a0d0b1f7edd66a01dac9b9d39fb81c3 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Wed, 1 Oct 2008 13:54:44 +0100 Subject: [PATCH] fsync implementation. --- MODULES.html.sh | 1 + NEWS | 2 + doc/posix-functions/fsync.texi | 8 ++-- lib/fsync.c | 62 ++++++++++++++++++++++++++++++++++++++++ lib/unistd.in.h | 17 +++++++++++ m4/fsync.m4 | 19 ++++++++++++ m4/unistd_h.m4 | 2 + modules/fsync | 24 +++++++++++++++ modules/unistd | 2 + 9 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 lib/fsync.c create mode 100644 m4/fsync.m4 create mode 100644 modules/fsync diff --git a/MODULES.html.sh b/MODULES.html.sh index afaf8ba..058125d 100755 --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -2110,6 +2110,7 @@ func_all_modules () func_module freopen func_module fseek func_module fseeko + func_module fsync func_module ftell func_module ftello func_module ftruncate diff --git a/NEWS b/NEWS index ef04cf4..4c6edfe 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ User visible incompatible changes Date Modules Changes +2008-10-01 fsync This function has been implemented for Windows. + 2008-09-28 sockets When using this module, you now need to link with $(LIBSOCKET). diff --git a/doc/posix-functions/fsync.texi b/doc/posix-functions/fsync.texi index 405be40..fb88214 100644 --- a/doc/posix-functions/fsync.texi +++ b/doc/posix-functions/fsync.texi @@ -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 address@hidden +This function is missing on some platforms: +mingw. @end itemize Portability problems not fixed by Gnulib: @itemize address@hidden -This function is missing on some platforms: -mingw. @end itemize diff --git a/lib/fsync.c b/lib/fsync.c new file mode 100644 index 0000000..e353ebf --- /dev/null +++ b/lib/fsync.c @@ -0,0 +1,62 @@ +/* Emulate fsync on platforms which lack it, primarily Windows and + cross-compilers like MinGW. + + This is derived from sqlite3 sources and is in the public domain. + + Written by Richard W.M. Jones +*/ + +#include +#include + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +/* _get_osfhandle */ +#include + +/* FlushFileBuffers */ +#define WIN32_LEAN_AND_MEAN +#include + +#include + +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 */ diff --git a/lib/unistd.in.h b/lib/unistd.in.h index e75b4cd..71eaa4d 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -140,6 +140,23 @@ extern int dup2 (int, int); #endif +#if @GNULIB_FSYNC@ +/* Synchronize changes to a file. + Return 0 if successful, otherwise -1 and errno set. + See POSIX:2001 specification + . */ +# if address@hidden@ +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 address@hidden@ /* Change the size of the file to which FD is opened to become equal to LENGTH. diff --git a/m4/fsync.m4 b/m4/fsync.m4 new file mode 100644 index 0000000..eac7409 --- /dev/null +++ b/m4/fsync.m4 @@ -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], [:]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index 0e76a52..9e9a56b 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -36,6 +36,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], 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 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], 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]) diff --git a/modules/fsync b/modules/fsync new file mode 100644 index 0000000..3de3ee3 --- /dev/null +++ b/modules/fsync @@ -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: + + +License: +Public Domain + +Maintainer: +Richard W.M. Jones, Jim Meyering diff --git a/modules/unistd b/modules/unistd index 9410778..efd97b5 100644 --- a/modules/unistd +++ b/modules/unistd @@ -28,6 +28,7 @@ unistd.h: unistd.in.h -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 @@ unistd.h: unistd.in.h -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' \ -- 1.6.0.1