diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-01-02 20:37:13 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-02 20:37:13 +0800 |
commit | 5322bf99e6d5247370d282d9013381bf98b5b832 (patch) | |
tree | 4ca4d03796ff82d2332f6a3b6ef7c19079fbd719 | |
parent | c590641febf4d03e89c46f8e7ef4c3fb2a455520 (diff) | |
download | rneovim-5322bf99e6d5247370d282d9013381bf98b5b832.tar.gz rneovim-5322bf99e6d5247370d282d9013381bf98b5b832.tar.bz2 rneovim-5322bf99e6d5247370d282d9013381bf98b5b832.zip |
vim-patch:8.2.0711: temp directory might be cleared (#21614)
Problem: With a long running Vim the temp directory might be cleared on
some systems.
Solution: Lock the temp directory. (closes vim/vim#6044)
https://github.com/vim/vim/commit/b2d0e51366dea6843f991f31a457f5456d162678
-rw-r--r-- | cmake.config/CMakeLists.txt | 20 | ||||
-rw-r--r-- | cmake.config/config.h.in | 2 | ||||
-rw-r--r-- | src/nvim/fileio.c | 41 |
3 files changed, 63 insertions, 0 deletions
diff --git a/cmake.config/CMakeLists.txt b/cmake.config/CMakeLists.txt index b11ee2d969..183954b889 100644 --- a/cmake.config/CMakeLists.txt +++ b/cmake.config/CMakeLists.txt @@ -46,6 +46,26 @@ check_function_exists(strcasecmp HAVE_STRCASECMP) check_function_exists(strncasecmp HAVE_STRNCASECMP) check_function_exists(strptime HAVE_STRPTIME) +check_c_source_compiles(" +#include <sys/types.h> +#include <dirent.h> +int main(void) +{ + DIR *dir = opendir(\"dirname\"); + dirfd(dir); + return 0; +} +" HAVE_DIRFD) + +check_c_source_compiles(" +#include <sys/file.h> +int main(void) +{ + flock(10, LOCK_SH); + return 0; +} +" HAVE_FLOCK) + if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") check_c_source_compiles(" #include <termios.h> diff --git a/cmake.config/config.h.in b/cmake.config/config.h.in index 283a1d0c47..f946fa6124 100644 --- a/cmake.config/config.h.in +++ b/cmake.config/config.h.in @@ -54,6 +54,8 @@ # undef HAVE_SYS_UIO_H # endif #endif +#cmakedefine HAVE_DIRFD +#cmakedefine HAVE_FLOCK #cmakedefine HAVE_FORKPTY #ifndef UNIT_TESTING diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index fdf1973719..6bad91e959 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -65,6 +65,11 @@ #include "nvim/undo.h" #include "nvim/vim.h" +#if defined(HAVE_FLOCK) && defined(HAVE_DIRFD) +# include <dirent.h> +# include <sys/file.h> +#endif + #ifdef OPEN_CHR_FILES # include "nvim/charset.h" #endif @@ -5167,6 +5172,9 @@ void forward_slash(char_u *fname) /// Path to Nvim's own temp dir. Ends in a slash. static char *vim_tempdir = NULL; +#if defined(HAVE_FLOCK) && defined(HAVE_DIRFD) +DIR *vim_tempdir_dp = NULL; ///< File descriptor of temp dir +#endif /// Creates a directory for private use by this instance of Nvim, trying each of /// `TEMP_DIR_NAMES` until one succeeds. @@ -5331,10 +5339,40 @@ int delete_recursive(const char *name) return result; } +#if defined(HAVE_FLOCK) && defined(HAVE_DIRFD) +/// Open temporary directory and take file lock to prevent +/// to be auto-cleaned. +static void vim_opentempdir(void) +{ + if (vim_tempdir_dp != NULL) { + return; + } + + DIR *dp = opendir(vim_tempdir); + + if (dp != NULL) { + vim_tempdir_dp = dp; + flock(dirfd(vim_tempdir_dp), LOCK_SH); + } +} + +/// Close temporary directory - it automatically release file lock. +static void vim_closetempdir(void) +{ + if (vim_tempdir_dp != NULL) { + closedir(vim_tempdir_dp); + vim_tempdir_dp = NULL; + } +} +#endif + /// Delete the temp directory and all files it contains. void vim_deltempdir(void) { if (vim_tempdir != NULL) { +#if defined(HAVE_FLOCK) && defined(HAVE_DIRFD) + vim_closetempdir(); +#endif // remove the trailing path separator path_tail(vim_tempdir)[-1] = NUL; delete_recursive(vim_tempdir); @@ -5370,6 +5408,9 @@ static bool vim_settempdir(char *tempdir) vim_FullName(tempdir, buf, MAXPATHL, false); add_pathsep(buf); vim_tempdir = xstrdup(buf); +#if defined(HAVE_FLOCK) && defined(HAVE_DIRFD) + vim_opentempdir(); +#endif xfree(buf); return true; } |