aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-01-02 20:37:13 +0800
committerGitHub <noreply@github.com>2023-01-02 20:37:13 +0800
commit5322bf99e6d5247370d282d9013381bf98b5b832 (patch)
tree4ca4d03796ff82d2332f6a3b6ef7c19079fbd719
parentc590641febf4d03e89c46f8e7ef4c3fb2a455520 (diff)
downloadrneovim-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.txt20
-rw-r--r--cmake.config/config.h.in2
-rw-r--r--src/nvim/fileio.c41
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;
}