0
0
mirror of https://github.com/vim/vim.git synced 2025-10-13 06:54:15 -04:00

patch 8.1.0915: fsync() may not work properly on Mac

Problem:    fsync() may not work properly on Mac.
Solution:   Use fcntl() with F_FULLFSYNC. (suggested by Justin M. Keyes)
This commit is contained in:
Bram Moolenaar
2019-02-14 12:56:36 +01:00
parent 5fd0f5052f
commit a787019518
5 changed files with 28 additions and 6 deletions

View File

@@ -14791,7 +14791,7 @@ f_writefile(typval_T *argvars, typval_T *rettv)
else if (do_fsync) else if (do_fsync)
// Ignore the error, the user wouldn't know what to do about it. // Ignore the error, the user wouldn't know what to do about it.
// May happen for a device. // May happen for a device.
vim_ignored = fsync(fileno(fd)); vim_ignored = vim_fsync(fileno(fd));
#endif #endif
fclose(fd); fclose(fd);
} }
@@ -14803,7 +14803,7 @@ f_writefile(typval_T *argvars, typval_T *rettv)
else if (do_fsync) else if (do_fsync)
/* Ignore the error, the user wouldn't know what to do about it. /* Ignore the error, the user wouldn't know what to do about it.
* May happen for a device. */ * May happen for a device. */
vim_ignored = fsync(fileno(fd)); vim_ignored = vim_fsync(fileno(fd));
#endif #endif
fclose(fd); fclose(fd);
} }

View File

@@ -4661,7 +4661,7 @@ restore_backup:
* work (could be a pipe). * work (could be a pipe).
* If the 'fsync' option is FALSE, don't fsync(). Useful for laptops. * If the 'fsync' option is FALSE, don't fsync(). Useful for laptops.
*/ */
if (p_fs && fsync(fd) != 0 && !device) if (p_fs && vim_fsync(fd) != 0 && !device)
{ {
errmsg = (char_u *)_(e_fsync); errmsg = (char_u *)_(e_fsync);
end = 0; end = 0;
@@ -5123,6 +5123,25 @@ nofail:
return retval; return retval;
} }
#if defined(HAVE_FSYNC) || defined(PROTO)
/*
* Call fsync() with Mac-specific exception.
* Return fsync() result: zero for success.
*/
int
vim_fsync(int fd)
{
int r;
# ifdef MACOS_X
r = fcntl(fd, F_FULLFSYNC);
if (r != 0 && errno == ENOTTY)
# endif
r = fsync(fd);
return r;
}
#endif
/* /*
* Set the name of the current buffer. Use when the buffer doesn't have a * Set the name of the current buffer. Use when the buffer doesn't have a
* name and a ":r" or ":w" command with a file name is used. * name and a ":r" or ":w" command with a file name is used.

View File

@@ -600,7 +600,7 @@ mf_sync(memfile_T *mfp, int flags)
*/ */
if (STRCMP(p_sws, "fsync") == 0) if (STRCMP(p_sws, "fsync") == 0)
{ {
if (fsync(mfp->mf_fd)) if (vim_fsync(mfp->mf_fd))
status = FAIL; status = FAIL;
} }
else else
@@ -617,7 +617,7 @@ mf_sync(memfile_T *mfp, int flags)
#ifdef VMS #ifdef VMS
if (STRCMP(p_sws, "fsync") == 0) if (STRCMP(p_sws, "fsync") == 0)
{ {
if (fsync(mfp->mf_fd)) if (vim_fsync(mfp->mf_fd))
status = FAIL; status = FAIL;
} }
#endif #endif
@@ -627,7 +627,7 @@ mf_sync(memfile_T *mfp, int flags)
#endif #endif
#ifdef AMIGA #ifdef AMIGA
# if defined(__AROS__) || defined(__amigaos4__) # if defined(__AROS__) || defined(__amigaos4__)
if (fsync(mfp->mf_fd) != 0) if (vim_fsync(mfp->mf_fd) != 0)
status = FAIL; status = FAIL;
# else # else
/* /*

View File

@@ -7,6 +7,7 @@ void set_file_options(int set_options, exarg_T *eap);
void set_forced_fenc(exarg_T *eap); void set_forced_fenc(exarg_T *eap);
int check_file_readonly(char_u *fname, int perm); int check_file_readonly(char_u *fname, int perm);
int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap, int append, int forceit, int reset_changed, int filtering); int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap, int append, int forceit, int reset_changed, int filtering);
int vim_fsync(int fd);
void msg_add_fname(buf_T *buf, char_u *fname); void msg_add_fname(buf_T *buf, char_u *fname);
void msg_add_lines(int insert_space, long lnum, off_T nchars); void msg_add_lines(int insert_space, long lnum, off_T nchars);
char_u *shorten_fname1(char_u *full_path); char_u *shorten_fname1(char_u *full_path);

View File

@@ -783,6 +783,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
915,
/**/ /**/
914, 914,
/**/ /**/