# HG changeset patch # User Bram Moolenaar # Date 1580057104 -3600 # Node ID 17d878a2ddaafcaf8451321345c5e91fa3eb832f # Parent 070b75b914657f63a8f15ccd3d12fded14efb1eb patch 8.2.0151: detecting a script was already sourced is unreliable Commit: https://github.com/vim/vim/commit/978d170bdce9c0a47e6683cd7c288bc2706f3fff Author: Bram Moolenaar Date: Sun Jan 26 17:38:12 2020 +0100 patch 8.2.0151: detecting a script was already sourced is unreliable Problem: Detecting a script was already sourced is unreliable. Solution: Do not use the inode number. diff --git a/src/scriptfile.c b/src/scriptfile.c --- a/src/scriptfile.c +++ b/src/scriptfile.c @@ -1091,10 +1091,6 @@ do_source( int save_debug_break_level = debug_break_level; int sid; scriptitem_T *si = NULL; -# ifdef UNIX - stat_T st; - int stat_ok; -# endif #endif #ifdef STARTUPTIME struct timeval tv_rel; @@ -1121,26 +1117,17 @@ do_source( #ifdef FEAT_EVAL // See if we loaded this script before. -# ifdef UNIX - stat_ok = (mch_stat((char *)fname_exp, &st) >= 0); -# endif for (sid = script_items.ga_len; sid > 0; --sid) { + // We used to check inode here, but that doesn't work: + // - If a script is edited and written, it may get a different + // inode number, even though to the user it is the same script. + // - If a script is deleted and another script is written, with a + // different name, the inode may be re-used. si = &SCRIPT_ITEM(sid); - if (si->sn_name != NULL) - { -# ifdef UNIX - // Compare dev/ino when possible, it catches symbolic links. Also - // compare file names, the inode may change when the file was - // edited or it may be re-used for another script (esp. in tests). - if ((stat_ok && si->sn_dev_valid) - && (si->sn_dev != st.st_dev || si->sn_ino != st.st_ino)) - continue; -# endif - if (fnamecmp(si->sn_name, fname_exp) == 0) + if (si->sn_name != NULL && fnamecmp(si->sn_name, fname_exp) == 0) // Found it! break; - } } if (sid > 0 && ret_sid != NULL) { @@ -1324,16 +1311,6 @@ do_source( si = &SCRIPT_ITEM(current_sctx.sc_sid); si->sn_name = fname_exp; fname_exp = vim_strsave(si->sn_name); // used for autocmd -# ifdef UNIX - if (stat_ok) - { - si->sn_dev_valid = TRUE; - si->sn_dev = st.st_dev; - si->sn_ino = st.st_ino; - } - else - si->sn_dev_valid = FALSE; -# endif if (ret_sid != NULL) *ret_sid = current_sctx.sc_sid; } diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -1665,11 +1665,6 @@ typedef struct int sn_had_command; // TRUE if any command was executed char_u *sn_save_cpo; // 'cpo' value when :vim9script found -# ifdef UNIX - int sn_dev_valid; - dev_t sn_dev; - ino_t sn_ino; -# endif # ifdef FEAT_PROFILE int sn_prof_on; // TRUE when script is/was profiled int sn_pr_force; // forceit: profile functions in this script diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -4,7 +4,7 @@ source check.vim " Check that "lines" inside ":def" results in an "error" message. func CheckDefFailure(lines, error) - call writefile(['def! Func()'] + a:lines + ['enddef'], 'Xdef') + call writefile(['def Func()'] + a:lines + ['enddef'], 'Xdef') call assert_fails('so Xdef', a:error, a:lines) call delete('Xdef') endfunc @@ -126,10 +126,10 @@ enddef def Test_return_type_wrong() " TODO: why is ! needed for Mac and FreeBSD? - CheckScriptFailure(['def! Func(): number', 'return "a"', 'enddef'], 'expected number but got string') - CheckScriptFailure(['def! Func(): string', 'return 1', 'enddef'], 'expected string but got number') - CheckScriptFailure(['def! Func(): void', 'return "a"', 'enddef'], 'expected void but got string') - CheckScriptFailure(['def! Func()', 'return "a"', 'enddef'], 'expected void but got string') + CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string') + CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number') + CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string') + CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string') enddef def Test_try_catch() diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 151, +/**/ 150, /**/ 149,