mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
shada: Use “write then rename” variant by default for writing shada
This commit is contained in:
parent
55712dcdb4
commit
602efe856a
@ -44,6 +44,7 @@
|
|||||||
#include "nvim/version.h"
|
#include "nvim/version.h"
|
||||||
#include "nvim/path.h"
|
#include "nvim/path.h"
|
||||||
#include "nvim/lib/ringbuf.h"
|
#include "nvim/lib/ringbuf.h"
|
||||||
|
#include "nvim/fileio.h"
|
||||||
#include "nvim/strings.h"
|
#include "nvim/strings.h"
|
||||||
#include "nvim/lib/khash.h"
|
#include "nvim/lib/khash.h"
|
||||||
#include "nvim/lib/kvec.h"
|
#include "nvim/lib/kvec.h"
|
||||||
@ -69,6 +70,8 @@ KHASH_MAP_INIT_STR(fnamebufs, buf_T *)
|
|||||||
#define emsgu(a, ...) emsgu((char_u *) a, __VA_ARGS__)
|
#define emsgu(a, ...) emsgu((char_u *) a, __VA_ARGS__)
|
||||||
#define home_replace_save(a, b) \
|
#define home_replace_save(a, b) \
|
||||||
((char *)home_replace_save(a, (char_u *)b))
|
((char *)home_replace_save(a, (char_u *)b))
|
||||||
|
#define vim_rename(a, b) \
|
||||||
|
(vim_rename((char_u *)a, (char_u *)b))
|
||||||
#define has_non_ascii(a) (has_non_ascii((char_u *)a))
|
#define has_non_ascii(a) (has_non_ascii((char_u *)a))
|
||||||
#define string_convert(a, b, c) \
|
#define string_convert(a, b, c) \
|
||||||
((char *)string_convert((vimconv_T *)a, (char_u *)b, c))
|
((char *)string_convert((vimconv_T *)a, (char_u *)b, c))
|
||||||
@ -395,7 +398,7 @@ open_file_start:
|
|||||||
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
if (-fd == ENOENT) {
|
if (-fd == ENOENT) {
|
||||||
return -1;
|
return fd;
|
||||||
}
|
}
|
||||||
if (-fd == ENOMEM && !did_try_to_free) {
|
if (-fd == ENOMEM && !did_try_to_free) {
|
||||||
try_to_free_memory();
|
try_to_free_memory();
|
||||||
@ -405,9 +408,11 @@ open_file_start:
|
|||||||
if (-fd == EINTR) {
|
if (-fd == EINTR) {
|
||||||
goto open_file_start;
|
goto open_file_start;
|
||||||
}
|
}
|
||||||
emsg3("System error while opening ShaDa file %s: %s",
|
if (-fd != EEXIST) {
|
||||||
fname, strerror(-fd));
|
emsg3("System error while opening ShaDa file %s: %s",
|
||||||
return -1;
|
fname, strerror(-fd));
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -424,7 +429,7 @@ static int open_shada_file_for_reading(const char *const fname,
|
|||||||
{
|
{
|
||||||
const intptr_t fd = (intptr_t) open_file(fname, O_RDONLY, 0);
|
const intptr_t fd = (intptr_t) open_file(fname, O_RDONLY, 0);
|
||||||
|
|
||||||
if (fd == -1) {
|
if (fd < 0) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,6 +441,8 @@ static int open_shada_file_for_reading(const char *const fname,
|
|||||||
.cookie = (void *) fd,
|
.cookie = (void *) fd,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
convert_setup(&sd_reader->sd_conv, "utf-8", p_enc);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,8 +538,6 @@ int shada_read_file(const char *const file, const int flags)
|
|||||||
return of_ret;
|
return of_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
convert_setup(&sd_reader.sd_conv, "utf-8", p_enc);
|
|
||||||
|
|
||||||
shada_read(&sd_reader, flags);
|
shada_read(&sd_reader, flags);
|
||||||
|
|
||||||
close_file((int)(intptr_t) sd_reader.cookie);
|
close_file((int)(intptr_t) sd_reader.cookie);
|
||||||
@ -1712,17 +1717,58 @@ static void shada_write(ShaDaWriteDef *const sd_writer,
|
|||||||
/// @param[in] nomerge If true then old file is ignored.
|
/// @param[in] nomerge If true then old file is ignored.
|
||||||
///
|
///
|
||||||
/// @return OK if writing was successfull, FAIL otherwise.
|
/// @return OK if writing was successfull, FAIL otherwise.
|
||||||
int shada_write_file(const char *const file, const bool nomerge)
|
int shada_write_file(const char *const file, bool nomerge)
|
||||||
{
|
{
|
||||||
char *const fname = shada_filename(file);
|
char *const fname = shada_filename(file);
|
||||||
|
char *tempname = NULL;
|
||||||
ShaDaWriteDef sd_writer = (ShaDaWriteDef) {
|
ShaDaWriteDef sd_writer = (ShaDaWriteDef) {
|
||||||
.write = &write_file,
|
.write = &write_file,
|
||||||
.error = NULL,
|
.error = NULL,
|
||||||
};
|
};
|
||||||
|
ShaDaReadDef sd_reader;
|
||||||
|
|
||||||
const intptr_t fd = (intptr_t) open_file(fname,
|
intptr_t fd;
|
||||||
O_CREAT|O_WRONLY|O_NOFOLLOW|O_TRUNC,
|
|
||||||
0600);
|
if (!nomerge) {
|
||||||
|
if (open_shada_file_for_reading(fname, &sd_reader) != OK) {
|
||||||
|
nomerge = true;
|
||||||
|
goto shada_write_file_nomerge;
|
||||||
|
}
|
||||||
|
tempname = modname(fname, ".tmp.a", false);
|
||||||
|
if (tempname == NULL) {
|
||||||
|
nomerge = true;
|
||||||
|
goto shada_write_file_nomerge;
|
||||||
|
}
|
||||||
|
|
||||||
|
shada_write_file_open:
|
||||||
|
fd = (intptr_t) open_file(tempname, O_CREAT|O_WRONLY|O_NOFOLLOW|O_EXCL,
|
||||||
|
0600);
|
||||||
|
if (fd < 0) {
|
||||||
|
if (-fd == EEXIST
|
||||||
|
#ifdef ELOOP
|
||||||
|
|| -fd == ELOOP
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
// File already exists, try another name
|
||||||
|
char *const wp = tempname + strlen(tempname) - 1;
|
||||||
|
if (*wp == 'z') {
|
||||||
|
// Tried names from .tmp.a to .tmp.z, all failed. Something must be
|
||||||
|
// wrong then.
|
||||||
|
xfree(fname);
|
||||||
|
xfree(tempname);
|
||||||
|
return FAIL;
|
||||||
|
} else {
|
||||||
|
(*wp)++;
|
||||||
|
goto shada_write_file_open;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nomerge) {
|
||||||
|
shada_write_file_nomerge:
|
||||||
|
fd = (intptr_t) open_file(fname, O_CREAT|O_WRONLY|O_TRUNC,
|
||||||
|
0600);
|
||||||
|
}
|
||||||
|
|
||||||
if (p_verbose > 0) {
|
if (p_verbose > 0) {
|
||||||
verbose_enter();
|
verbose_enter();
|
||||||
@ -1730,8 +1776,9 @@ int shada_write_file(const char *const file, const bool nomerge)
|
|||||||
verbose_leave();
|
verbose_leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree(fname);
|
if (fd < 0) {
|
||||||
if (fd == -1) {
|
xfree(fname);
|
||||||
|
xfree(tempname);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1742,6 +1789,19 @@ int shada_write_file(const char *const file, const bool nomerge)
|
|||||||
shada_write(&sd_writer, NULL);
|
shada_write(&sd_writer, NULL);
|
||||||
|
|
||||||
close_file((int)(intptr_t) sd_writer.cookie);
|
close_file((int)(intptr_t) sd_writer.cookie);
|
||||||
|
|
||||||
|
if (!nomerge) {
|
||||||
|
close_file((int)(intptr_t) sd_reader.cookie);
|
||||||
|
if (vim_rename(tempname, fname) == -1) {
|
||||||
|
EMSG3(_("E886: Can't rename viminfo file from %s to %s!"),
|
||||||
|
tempname, fname);
|
||||||
|
} else {
|
||||||
|
os_remove(tempname);
|
||||||
|
}
|
||||||
|
xfree(tempname);
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree(fname);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user