aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/starting.txt5
-rw-r--r--src/nvim/shada.c74
2 files changed, 33 insertions, 46 deletions
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index 03e64db430..0712888284 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -1121,10 +1121,7 @@ include:
Such errors are listed at |shada-critical-contents-errors|.
- If writing to the temporary file failed: e.g. because of the insufficient
space left.
-- If renaming file failed: e.g. because of insufficient permissions. On Unix
- permissions are checked before trying to create even the temporary file, so
- permission error can only happen if permissions were changed after starting
- to edit the temporary file and before renaming it.
+- If renaming file failed: e.g. because of insufficient permissions.
- If target ShaDa file has different from the Neovim instance's owners (user
and group) and changing them failed. Unix-specific, applies only when
Neovim was launched from root.
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index d20f05ee2b..931636b030 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -2903,11 +2903,6 @@ int shada_write_file(const char *const file, bool nomerge)
.error = NULL,
};
ShaDaReadDef sd_reader;
-#ifdef UNIX
- bool do_fchown = false;
- uv_uid_t old_uid = (uv_uid_t) -1;
- uv_gid_t old_gid = (uv_gid_t) -1;
-#endif
intptr_t fd;
@@ -2916,31 +2911,6 @@ int shada_write_file(const char *const file, bool nomerge)
nomerge = true;
goto shada_write_file_nomerge;
}
-#ifdef UNIX
- // For Unix we check the owner of the file. It's not very nice to
- // overwrite a user’s viminfo file after a "su root", with a
- // viminfo file that the user can't read.
- FileInfo old_info;
- if (os_fileinfo((char *)fname, &old_info)) {
- if (getuid() == ROOT_UID) {
- if (old_info.stat.st_uid != ROOT_UID
- || old_info.stat.st_gid != getgid()) {
- do_fchown = true;
- old_uid = (uv_uid_t) old_info.stat.st_uid;
- old_gid = (uv_gid_t) old_info.stat.st_gid;
- }
- } else if (!(old_info.stat.st_uid == getuid()
- ? (old_info.stat.st_mode & 0200)
- : (old_info.stat.st_gid == getgid()
- ? (old_info.stat.st_mode & 0020)
- : (old_info.stat.st_mode & 0002)))) {
- EMSG2(_("E137: ShaDa file is not writable: %s"), fname);
- sd_reader.close(&sd_reader);
- xfree(fname);
- return FAIL;
- }
- }
-#endif
tempname = modname(fname, ".tmp.a", false);
if (tempname == NULL) {
nomerge = true;
@@ -3024,27 +2994,47 @@ shada_write_file_nomerge: {}
const ShaDaWriteResult sw_ret = shada_write(&sd_writer, (nomerge
? NULL
: &sd_reader));
-#ifdef UNIX
- if (!do_fchown) {
-#endif
- sd_writer.close(&sd_writer);
-#ifdef UNIX
- }
+#ifndef UNIX
+ sd_writer.close(&sd_writer);
#endif
if (!nomerge) {
sd_reader.close(&sd_reader);
bool did_remove = false;
if (sw_ret == kSDWriteSuccessfull) {
#ifdef UNIX
- if (do_fchown) {
- const int fchown_ret = os_fchown((int) fd, old_uid, old_gid);
- sd_writer.close(&sd_writer);
- if (fchown_ret != 0) {
- EMSG3(_(RNERR "Failed setting uid and gid for file %s: %s"),
- tempname, os_strerror(fchown_ret));
+ bool closed = false;
+ // For Unix we check the owner of the file. It's not very nice to
+ // overwrite a user’s viminfo file after a "su root", with a
+ // viminfo file that the user can't read.
+ FileInfo old_info;
+ if (os_fileinfo((char *)fname, &old_info)) {
+ if (getuid() == ROOT_UID) {
+ if (old_info.stat.st_uid != ROOT_UID
+ || old_info.stat.st_gid != getgid()) {
+ const uv_uid_t old_uid = (uv_uid_t) old_info.stat.st_uid;
+ const uv_gid_t old_gid = (uv_gid_t) old_info.stat.st_gid;
+ const int fchown_ret = os_fchown((int) fd, old_uid, old_gid);
+ sd_writer.close(&sd_writer);
+ if (fchown_ret != 0) {
+ EMSG3(_(RNERR "Failed setting uid and gid for file %s: %s"),
+ tempname, os_strerror(fchown_ret));
+ goto shada_write_file_did_not_remove;
+ }
+ closed = true;
+ }
+ } else if (!(old_info.stat.st_uid == getuid()
+ ? (old_info.stat.st_mode & 0200)
+ : (old_info.stat.st_gid == getgid()
+ ? (old_info.stat.st_mode & 0020)
+ : (old_info.stat.st_mode & 0002)))) {
+ EMSG2(_("E137: ShaDa file is not writable: %s"), fname);
+ sd_writer.close(&sd_writer);
goto shada_write_file_did_not_remove;
}
}
+ if (!closed) {
+ sd_writer.close(&sd_writer);
+ }
#endif
if (vim_rename(tempname, fname) == -1) {
EMSG3(_(RNERR "Can't rename ShaDa file from %s to %s!"),