changeset 20311:05b4efb062a7 v8.2.0711

patch 8.2.0711: temp directory might be cleared Commit: https://github.com/vim/vim/commit/b2d0e51366dea6843f991f31a457f5456d162678 Author: Bram Moolenaar <Bram@vim.org> Date: Thu May 7 18:37:03 2020 +0200 patch 8.2.0711: temp directory might be cleared Problem: With a long running Vim the temp directory might be cleared on some systems. Solution: Lock the temp directory. (closes #6044)
author Bram Moolenaar <Bram@vim.org>
date Thu, 07 May 2020 18:45:03 +0200
parents fb099a566102
children 0742d56da9b2
files src/auto/configure src/config.h.in src/configure.ac src/fileio.c src/globals.h src/os_unix.h src/version.c
diffstat 7 files changed, 119 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -4060,6 +4060,21 @@ AC_TRY_LINK([#include <stdio.h>], [renam
 	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(
--- 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);
     }
 }
--- a/src/globals.h
+++ b/src/globals.h
@@ -758,6 +758,9 @@ EXTERN int	ru_wid;		// 'rulerfmt' width 
 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
--- 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
--- 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,