Port fsync() to libuv.

This commit is contained in:
Seth Jackson 2015-10-17 01:21:50 +01:00
parent d8a2007d47
commit 648aebb8b6
9 changed files with 52 additions and 68 deletions

View File

@ -38,7 +38,6 @@ check_include_files(utime.h HAVE_UTIME_H)
# Functions
check_function_exists(fseeko HAVE_FSEEKO)
check_function_exists(fsync HAVE_FSYNC)
check_function_exists(getpwent HAVE_GETPWENT)
check_function_exists(getpwnam HAVE_GETPWNAM)
check_function_exists(getpwuid HAVE_GETPWUID)
@ -101,10 +100,10 @@ endif()
if (NOT "${HAVE_BE64TOH}")
if (NOT "${CMAKE_CROSSCOMPILING}")
# It is safe to make ORDER_BIG_ENDIAN not defined if
# - HAVE_BE64TOH is true. In this case be64toh will be used unconditionally in
# - HAVE_BE64TOH is true. In this case be64toh will be used unconditionally in
# any case and ORDER_BIG_ENDIAN will not be examined.
# - CMAKE_CROSSCOMPILING *and* HAVE_BE64TOH are both false. In this case
# be64toh function which uses cycle and arithmetic operations is used which
# - CMAKE_CROSSCOMPILING *and* HAVE_BE64TOH are both false. In this case
# be64toh function which uses cycle and arithmetic operations is used which
# will work regardless of endianess. Function is sub-optimal though.
check_c_source_runs("
${SI}

View File

@ -18,7 +18,6 @@
#cmakedefine HAVE_FCNTL_H
#cmakedefine HAVE_FD_CLOEXEC
#cmakedefine HAVE_FSEEKO
#cmakedefine HAVE_FSYNC
#cmakedefine HAVE_GETPWENT
#cmakedefine HAVE_GETPWNAM
#cmakedefine HAVE_GETPWUID

View File

@ -2821,9 +2821,7 @@ A jump table for the options with a short description can be found at |Q_op|.
written even on filesystems which do metadata-only journaling. This
will force the harddrive to spin up on Linux systems running in laptop
mode, so it may be undesirable in some situations. Be warned that
turning this off increases the chances of data loss after a crash. On
systems without an fsync() implementation, this variable is always
off.
turning this off increases the chances of data loss after a crash.
Also see 'swapsync' for controlling fsync() on swap files.
*'gdefault'* *'gd'* *'nogdefault'* *'nogd'*
@ -6220,14 +6218,12 @@ A jump table for the options with a short description can be found at |Q_op|.
'swapsync' 'sws' string (default "fsync")
global
When this option is not empty a swap file is synced to disk after
writing to it. This takes some time, especially on busy unix systems.
writing to it. This takes some time, especially on busy Unix systems.
When this option is empty parts of the swap file may be in memory and
not written to disk. When the system crashes you may lose more work.
On Unix the system does a sync now and then without Vim asking for it,
so the disadvantage of setting this option off is small. On some
systems the swap file will not be written at all. For a unix system
setting it to "sync" will use the sync() call instead of the default
fsync(), which may work better on some systems.
systems the swap file will not be written at all.
The 'fsync' option is used for the actual file.
*'switchbuf'* *'swb'*

View File

@ -3368,16 +3368,16 @@ restore_backup:
nchars += len;
}
#if defined(UNIX) && defined(HAVE_FSYNC)
/* On many journalling file systems there is a bug that causes both the
* original and the backup file to be lost when halting the system right
* after writing the file. That's because only the meta-data is
* journalled. Syncing the file slows down the system, but assures it has
* been written to disk and we don't lose it.
* For a device do try the fsync() but don't complain if it does not work
* (could be a pipe).
* If the 'fsync' option is FALSE, don't fsync(). Useful for laptops. */
if (p_fs && fsync(fd) != 0 && !device) {
#if defined(UNIX)
// On many journalling file systems there is a bug that causes both the
// original and the backup file to be lost when halting the system right
// after writing the file. That's because only the meta-data is
// journalled. Syncing the file slows down the system, but assures it has
// been written to disk and we don't lose it.
// For a device do try the fsync() but don't complain if it does not work
// (could be a pipe).
// If the 'fsync' option is FALSE, don't fsync(). Useful for laptops.
if (p_fs && os_fsync(fd) != 0 && !device) {
errmsg = (char_u *)_("E667: Fsync failed");
end = 0;
}

View File

@ -460,31 +460,11 @@ int mf_sync(memfile_T *mfp, int flags)
mfp->mf_dirty = false;
if ((flags & MFS_FLUSH) && *p_sws != NUL) {
#if defined(UNIX)
# ifdef HAVE_FSYNC
if (STRCMP(p_sws, "fsync") == 0) {
if (fsync(mfp->mf_fd))
if (os_fsync(mfp->mf_fd)) {
status = FAIL;
} else {
# endif
// OpenNT is strictly POSIX (Benzinger).
// Tandem/Himalaya NSK-OSS doesn't have sync()
# if defined(__OPENNT) || defined(__TANDEM)
fflush(NULL);
# else
sync();
# endif
# ifdef HAVE_FSYNC
}
}
# endif
#endif
# ifdef SYNC_DUP_CLOSE
// Win32 is a bit more work: Duplicate the file handle and close it.
// This should flush the file to disk.
int fd;
if ((fd = dup(mfp->mf_fd)) >= 0)
close(fd);
# endif
}
got_int |= got_int_save;

View File

@ -405,27 +405,25 @@ static char *(p_fdo_values[]) = {"all", "block", "hor", "mark", "percent",
# define FDO_INSERT 0x100
# define FDO_UNDO 0x200
# define FDO_JUMP 0x400
EXTERN char_u *p_fp; /* 'formatprg' */
#ifdef HAVE_FSYNC
EXTERN int p_fs; /* 'fsync' */
#endif
EXTERN int p_gd; /* 'gdefault' */
EXTERN char_u *p_pdev; /* 'printdevice' */
EXTERN char_u *p_penc; /* 'printencoding' */
EXTERN char_u *p_pexpr; /* 'printexpr' */
EXTERN char_u *p_pmfn; /* 'printmbfont' */
EXTERN char_u *p_pmcs; /* 'printmbcharset' */
EXTERN char_u *p_pfn; /* 'printfont' */
EXTERN char_u *p_popt; /* 'printoptions' */
EXTERN char_u *p_header; /* 'printheader' */
EXTERN int p_prompt; /* 'prompt' */
EXTERN char_u *p_guicursor; /* 'guicursor' */
EXTERN char_u *p_hf; /* 'helpfile' */
EXTERN long p_hh; /* 'helpheight' */
EXTERN char_u *p_hlg; /* 'helplang' */
EXTERN int p_hid; /* 'hidden' */
/* Use P_HID to check if a buffer is to be hidden when it is no longer
* visible in a window. */
EXTERN char_u *p_fp; // 'formatprg'
EXTERN int p_fs; // 'fsync'
EXTERN int p_gd; // 'gdefault'
EXTERN char_u *p_pdev; // 'printdevice'
EXTERN char_u *p_penc; // 'printencoding'
EXTERN char_u *p_pexpr; // 'printexpr'
EXTERN char_u *p_pmfn; // 'printmbfont'
EXTERN char_u *p_pmcs; // 'printmbcharset'
EXTERN char_u *p_pfn; // 'printfont'
EXTERN char_u *p_popt; // 'printoptions'
EXTERN char_u *p_header; // 'printheader'
EXTERN int p_prompt; // 'prompt'
EXTERN char_u *p_guicursor; // 'guicursor'
EXTERN char_u *p_hf; // 'helpfile'
EXTERN long p_hh; // 'helpheight'
EXTERN char_u *p_hlg; // 'helplang'
EXTERN int p_hid; // 'hidden'
// Use P_HID to check if a buffer is to be hidden when it is no longer
// visible in a window.
# define P_HID(buf) (buf_hide(buf))
EXTERN char_u *p_hl; /* 'highlight' */
EXTERN int p_hls; /* 'hlsearch' */

View File

@ -959,7 +959,6 @@ return {
type='bool', scope={'global'},
secure=true,
vi_def=true,
enable_if='HAVE_FSYNC',
varname='p_fs',
defaults={if_true={vi=true}}
},

View File

@ -202,6 +202,19 @@ int os_open(const char* path, int flags, int mode)
return r;
}
/// Flushes file modifications to disk.
///
/// @param fd the file descriptor of the file to flush to disk.
///
/// @return `0` on success, a libuv error code on failure.
int os_fsync(int fd)
{
uv_fs_t fsync_req;
int r = uv_fs_fsync(&fs_loop, &fsync_req, fd, NULL);
uv_fs_req_cleanup(&fsync_req);
return r;
}
/// Get stat information for a file.
///
/// @return libuv return code.

View File

@ -761,9 +761,9 @@ static void close_sd_writer(ShaDaWriteDef *const sd_writer)
FUNC_ATTR_NONNULL_ALL
{
const int fd = (int)(intptr_t) sd_writer->cookie;
if (fsync(fd) < 0) {
if (os_fsync(fd) < 0) {
emsg2(_(SERR "System error while synchronizing ShaDa file: %s"),
strerror(errno));
os_strerror(errno));
errno = 0;
}
close_file(fd);