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)

b2d0e51366
This commit is contained in:
zeertzjq
2023-01-02 20:37:13 +08:00
committed by GitHub
parent c590641feb
commit 5322bf99e6
3 changed files with 63 additions and 0 deletions

View File

@@ -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>

View File

@@ -54,6 +54,8 @@
# undef HAVE_SYS_UIO_H
# endif
#endif
#cmakedefine HAVE_DIRFD
#cmakedefine HAVE_FLOCK
#cmakedefine HAVE_FORKPTY
#ifndef UNIT_TESTING

View File

@@ -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;
}