fsync.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /* Emulate fsync on platforms that lack it, primarily Windows and
  2. cross-compilers like MinGW.
  3. This is derived from sqlite3 sources.
  4. http://www.sqlite.org/cvstrac/rlog?f=sqlite/src/os_win.c
  5. http://www.sqlite.org/copyright.html
  6. Written by Richard W.M. Jones <rjones.at.redhat.com>
  7. Copyright (C) 2008-2015 Free Software Foundation, Inc.
  8. This library is free software; you can redistribute it and/or
  9. modify it under the terms of the GNU General Public
  10. License as published by the Free Software Foundation; either
  11. version 3 of the License, or (at your option) any later version.
  12. This library is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  18. #include <config.h>
  19. #include <unistd.h>
  20. #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  21. /* FlushFileBuffers */
  22. # define WIN32_LEAN_AND_MEAN
  23. # include <windows.h>
  24. # include <errno.h>
  25. /* Get _get_osfhandle. */
  26. # include "msvc-nothrow.h"
  27. int
  28. fsync (int fd)
  29. {
  30. HANDLE h = (HANDLE) _get_osfhandle (fd);
  31. DWORD err;
  32. if (h == INVALID_HANDLE_VALUE)
  33. {
  34. errno = EBADF;
  35. return -1;
  36. }
  37. if (!FlushFileBuffers (h))
  38. {
  39. /* Translate some Windows errors into rough approximations of Unix
  40. * errors. MSDN is useless as usual - in this case it doesn't
  41. * document the full range of errors.
  42. */
  43. err = GetLastError ();
  44. switch (err)
  45. {
  46. case ERROR_ACCESS_DENIED:
  47. /* For a read-only handle, fsync should succeed, even though we have
  48. no way to sync the access-time changes. */
  49. return 0;
  50. /* eg. Trying to fsync a tty. */
  51. case ERROR_INVALID_HANDLE:
  52. errno = EINVAL;
  53. break;
  54. default:
  55. errno = EIO;
  56. }
  57. return -1;
  58. }
  59. return 0;
  60. }
  61. #else /* !Windows */
  62. # error "This platform lacks fsync function, and Gnulib doesn't provide a replacement. This is a bug in Gnulib."
  63. #endif /* !Windows */