diff options
| author | Qiming zhao <chemzqm@gmail.com> | 2026-10-02 17:27:03 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-10-03 08:27:03 +0800 |
| commit | 1dc9728dbd4cb07f07dbfae92e857452f23a2849 (patch) | |
| tree | c16ad13d2b5761d5c9164eac99e646b072ee31d4 /src/nvim/lua/executor.c | |
| parent | 368fca018645baba4aefb7b3159de15c469368be (diff) | |
| download | rneovim-1dc9728dbd4cb07f07dbfae92e857452f23a2849.tar.gz rneovim-1dc9728dbd4cb07f07dbfae92e857452f23a2849.tar.bz2 rneovim-1dc9728dbd4cb07f07dbfae92e857452f23a2849.zip | |
fix(fileio): do not remove destination file before rename (#42152)
* fix(fileio): do not remove destination file before rename
Problem:
`vim_rename()` unconditionally removes the destination file `to` via
`os_remove(to)` before calling `os_rename(from, to)`.
If Neovim is killed or a crash occurs between `os_remove()` and
`os_rename()`, the destination file is lost. For example, during
`shada_write_file()`, `main.shada` is deleted before being replaced by
`main.shada.tmp.a`, which can lead to silent loss of command history,
marks, and registers. Furthermore, if `os_rename()` subsequently fails,
the destination was already destroyed.
Solution:
In Neovim, `os_rename()` uses `uv_fs_rename()`, which atomically replaces
existing destination files on both POSIX (`rename(2)`) and Windows
(`MoveFileExW(..., MOVEFILE_REPLACE_EXISTING)`).
Attempt `os_rename(from, to)` first. Only if it fails (e.g. cross-device
link) and copying is required as a fallback, remove `to` before
`vim_copyfile()`.
Fixes #41940
AI-assisted
* fix(fileio): retry rename after removing destination
Retry the native rename after successfully removing the destination so a
directory can still replace an existing file. Keep the initial rename
attempt before removal and the existing copy fallback.
AI-assisted
Diffstat (limited to 'src/nvim/lua/executor.c')
0 files changed, 0 insertions, 0 deletions