]> granicus.if.org Git - vim/commitdiff
patch 8.2.0711: temp directory might be cleared v8.2.0711
authorBram Moolenaar <Bram@vim.org>
Thu, 7 May 2020 16:37:03 +0000 (18:37 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 7 May 2020 16:37:03 +0000 (18:37 +0200)
Problem:    With a long running Vim the temp directory might be cleared on
            some systems.
Solution:   Lock the temp directory. (closes #6044)

src/auto/configure
src/config.h.in
src/configure.ac
src/fileio.c
src/globals.h
src/os_unix.h
src/version.c

index 6087e0e5aff3a7b2b9738df7e6c946a27f677a70..659ef82c91b06149bd8fa7a0ef04c38dee4ec528 100755 (executable)
 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
index de53ffb0300f581830e7d05a5e55df3a1fa0e640..5c8c7e55619e5bda12851e7dc0a72b0522721fa8 100644 (file)
 /* 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
index 687bdf95d298843b426e1cbe276bf12c4cd9ed8f..8751b2e63b30204099060093926cb7b0e95841e5 100644 (file)
@@ -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(
index f05abe68c99accfa08b4bdba8538fbc27cf8f52c..613f92359dfeff563bdc632f66c50d4ac6038491 100644 (file)
@@ -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);
     }
 }
index 9180befcb5291eaf9a6f4e0f1ebdb0166ac1adf7..5dfb6ff3f1642781fd5a5437ce415f02f707784e 100644 (file)
@@ -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
index 485e05775579419e6da0d6d27536eab1c18b5b44..9b7337ac19c16a70b308ea6baf329c6ae233db44 100644 (file)
 # endif
 #endif
 
+#ifdef HAVE_FLOCK
+# include <sys/file.h>
+#endif
+
 #endif // PROTO
 
 #ifdef VMS
index 2004f564d14ac0bda95a6f0117ae91c4c0c19157..d63cc8b8c9bc2636b5f081c5cdeb1d265e2ec429 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    711,
 /**/
     710,
 /**/