diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-05-07 18:37:03 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-05-07 18:37:03 +0200 |
commit | b2d0e51366dea6843f991f31a457f5456d162678 (patch) | |
tree | c220d988cb585427bf0e4eae0fc648ec3d0524d5 | |
parent | 4a070cc82e00618db279526797564cb2b4e9b060 (diff) | |
download | vim-git-b2d0e51366dea6843f991f31a457f5456d162678.tar.gz |
patch 8.2.0711: temp directory might be clearedv8.2.0711
Problem: With a long running Vim the temp directory might be cleared on
some systems.
Solution: Lock the temp directory. (closes #6044)
-rwxr-xr-x | src/auto/configure | 47 | ||||
-rw-r--r-- | src/config.h.in | 6 | ||||
-rw-r--r-- | src/configure.ac | 15 | ||||
-rw-r--r-- | src/fileio.c | 42 | ||||
-rw-r--r-- | src/globals.h | 3 | ||||
-rw-r--r-- | src/os_unix.h | 4 | ||||
-rw-r--r-- | src/version.c | 2 |
7 files changed, 119 insertions, 0 deletions
diff --git a/src/auto/configure b/src/auto/configure index 6087e0e5a..659ef82c9 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -13823,6 +13823,53 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dirfd" >&5 +$as_echo_n "checking for dirfd... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <dirent.h> +int +main () +{ +DIR * dir=opendir("dirname"); dirfd(dir); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; $as_echo "#define HAVE_DIRFD 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not usable" >&5 +$as_echo "not usable" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock" >&5 +$as_echo_n "checking for flock... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/file.h> +int +main () +{ +flock(10, LOCK_SH); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; $as_echo "#define HAVE_FLOCK 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not usable" >&5 +$as_echo "not usable" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysctl" >&5 $as_echo_n "checking for sysctl... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext diff --git a/src/config.h.in b/src/config.h.in index de53ffb03..5c8c7e556 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -484,5 +484,11 @@ /* Define if we have isnan() */ #undef HAVE_ISNAN +/* Define if we have dirfd() */ +#undef HAVE_DIRFD + +/* Define if we have flock() */ +#undef HAVE_FLOCK + /* Define to inline symbol or empty */ #undef inline diff --git a/src/configure.ac b/src/configure.ac index 687bdf95d..8751b2e63 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -4060,6 +4060,21 @@ AC_TRY_LINK([#include <stdio.h>], [rename("this", "that")], AC_MSG_RESULT(yes); AC_DEFINE(HAVE_RENAME), AC_MSG_RESULT(no)) +dnl check for dirfd() +AC_MSG_CHECKING(for dirfd) +AC_TRY_COMPILE( +[#include <sys/types.h> +#include <dirent.h>], +[DIR * dir=opendir("dirname"); dirfd(dir);], +AC_MSG_RESULT(yes); AC_DEFINE(HAVE_DIRFD), AC_MSG_RESULT(not usable)) + +dnl check for flock() +AC_MSG_CHECKING(for flock) +AC_TRY_COMPILE( +[#include <sys/file.h>], +[flock(10, LOCK_SH);], +AC_MSG_RESULT(yes); AC_DEFINE(HAVE_FLOCK), AC_MSG_RESULT(not usable)) + dnl sysctl() may exist but not the arguments we use AC_MSG_CHECKING(for sysctl) AC_TRY_COMPILE( diff --git a/src/fileio.c b/src/fileio.c index f05abe68c..613f92359 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -4620,6 +4620,42 @@ delete_recursive(char_u *name) #if defined(TEMPDIRNAMES) || defined(PROTO) static long temp_count = 0; // Temp filename counter. +# if defined(UNIX) && defined(HAVE_FLOCK) && defined(HAVE_DIRFD) +/* + * Open temporary directory and take file lock to prevent + * to be auto-cleaned. + */ + static void +vim_opentempdir(void) +{ + DIR *dp = NULL; + + if (vim_tempdir_dp != NULL) + return; + + dp = opendir((const char*)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. */ @@ -4628,6 +4664,9 @@ vim_deltempdir(void) { if (vim_tempdir != NULL) { +# if defined(UNIX) && defined(HAVE_FLOCK) && defined(HAVE_DIRFD) + vim_closetempdir(); +# endif // remove the trailing path separator gettail(vim_tempdir)[-1] = NUL; delete_recursive(vim_tempdir); @@ -4652,6 +4691,9 @@ vim_settempdir(char_u *tempdir) STRCPY(buf, tempdir); add_pathsep(buf); vim_tempdir = vim_strsave(buf); +# if defined(UNIX) && defined(HAVE_FLOCK) && defined(HAVE_DIRFD) + vim_opentempdir(); +# endif vim_free(buf); } } diff --git a/src/globals.h b/src/globals.h index 9180befcb..5dfb6ff3f 100644 --- a/src/globals.h +++ b/src/globals.h @@ -758,6 +758,9 @@ EXTERN int ru_wid; // 'rulerfmt' width of ruler when non-zero EXTERN int sc_col; // column for shown command #ifdef TEMPDIRNAMES +# if defined(UNIX) && defined(HAVE_FLOCK) && defined(HAVE_DIRFD) +EXTERN DIR *vim_tempdir_dp INIT(= NULL); // File descriptor of temp dir +# endif EXTERN char_u *vim_tempdir INIT(= NULL); // Name of Vim's own temp dir. // Ends in a slash. #endif diff --git a/src/os_unix.h b/src/os_unix.h index 485e05775..9b7337ac1 100644 --- a/src/os_unix.h +++ b/src/os_unix.h @@ -204,6 +204,10 @@ # endif #endif +#ifdef HAVE_FLOCK +# include <sys/file.h> +#endif + #endif // PROTO #ifdef VMS diff --git a/src/version.c b/src/version.c index 2004f564d..d63cc8b8c 100644 --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 711, +/**/ 710, /**/ 709, |