Mercurial > vim
comparison src/scriptfile.c @ 19185:17d878a2ddaa v8.2.0151
patch 8.2.0151: detecting a script was already sourced is unreliable
Commit: https://github.com/vim/vim/commit/978d170bdce9c0a47e6683cd7c288bc2706f3fff
Author: Bram Moolenaar <Bram@vim.org>
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.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 26 Jan 2020 17:45:04 +0100 |
parents | 94eda51ba9ba |
children | 133ef7ba4e4e |
comparison
equal
deleted
inserted
replaced
19184:070b75b91465 | 19185:17d878a2ddaa |
---|---|
1089 static int last_current_SID_seq = 0; | 1089 static int last_current_SID_seq = 0; |
1090 funccal_entry_T funccalp_entry; | 1090 funccal_entry_T funccalp_entry; |
1091 int save_debug_break_level = debug_break_level; | 1091 int save_debug_break_level = debug_break_level; |
1092 int sid; | 1092 int sid; |
1093 scriptitem_T *si = NULL; | 1093 scriptitem_T *si = NULL; |
1094 # ifdef UNIX | |
1095 stat_T st; | |
1096 int stat_ok; | |
1097 # endif | |
1098 #endif | 1094 #endif |
1099 #ifdef STARTUPTIME | 1095 #ifdef STARTUPTIME |
1100 struct timeval tv_rel; | 1096 struct timeval tv_rel; |
1101 struct timeval tv_start; | 1097 struct timeval tv_start; |
1102 #endif | 1098 #endif |
1119 goto theend; | 1115 goto theend; |
1120 } | 1116 } |
1121 | 1117 |
1122 #ifdef FEAT_EVAL | 1118 #ifdef FEAT_EVAL |
1123 // See if we loaded this script before. | 1119 // See if we loaded this script before. |
1124 # ifdef UNIX | |
1125 stat_ok = (mch_stat((char *)fname_exp, &st) >= 0); | |
1126 # endif | |
1127 for (sid = script_items.ga_len; sid > 0; --sid) | 1120 for (sid = script_items.ga_len; sid > 0; --sid) |
1128 { | 1121 { |
1122 // We used to check inode here, but that doesn't work: | |
1123 // - If a script is edited and written, it may get a different | |
1124 // inode number, even though to the user it is the same script. | |
1125 // - If a script is deleted and another script is written, with a | |
1126 // different name, the inode may be re-used. | |
1129 si = &SCRIPT_ITEM(sid); | 1127 si = &SCRIPT_ITEM(sid); |
1130 if (si->sn_name != NULL) | 1128 if (si->sn_name != NULL && fnamecmp(si->sn_name, fname_exp) == 0) |
1131 { | |
1132 # ifdef UNIX | |
1133 // Compare dev/ino when possible, it catches symbolic links. Also | |
1134 // compare file names, the inode may change when the file was | |
1135 // edited or it may be re-used for another script (esp. in tests). | |
1136 if ((stat_ok && si->sn_dev_valid) | |
1137 && (si->sn_dev != st.st_dev || si->sn_ino != st.st_ino)) | |
1138 continue; | |
1139 # endif | |
1140 if (fnamecmp(si->sn_name, fname_exp) == 0) | |
1141 // Found it! | 1129 // Found it! |
1142 break; | 1130 break; |
1143 } | |
1144 } | 1131 } |
1145 if (sid > 0 && ret_sid != NULL) | 1132 if (sid > 0 && ret_sid != NULL) |
1146 { | 1133 { |
1147 // Already loaded and no need to load again, return here. | 1134 // Already loaded and no need to load again, return here. |
1148 *ret_sid = sid; | 1135 *ret_sid = sid; |
1322 # endif | 1309 # endif |
1323 } | 1310 } |
1324 si = &SCRIPT_ITEM(current_sctx.sc_sid); | 1311 si = &SCRIPT_ITEM(current_sctx.sc_sid); |
1325 si->sn_name = fname_exp; | 1312 si->sn_name = fname_exp; |
1326 fname_exp = vim_strsave(si->sn_name); // used for autocmd | 1313 fname_exp = vim_strsave(si->sn_name); // used for autocmd |
1327 # ifdef UNIX | |
1328 if (stat_ok) | |
1329 { | |
1330 si->sn_dev_valid = TRUE; | |
1331 si->sn_dev = st.st_dev; | |
1332 si->sn_ino = st.st_ino; | |
1333 } | |
1334 else | |
1335 si->sn_dev_valid = FALSE; | |
1336 # endif | |
1337 if (ret_sid != NULL) | 1314 if (ret_sid != NULL) |
1338 *ret_sid = current_sctx.sc_sid; | 1315 *ret_sid = current_sctx.sc_sid; |
1339 } | 1316 } |
1340 | 1317 |
1341 # ifdef FEAT_PROFILE | 1318 # ifdef FEAT_PROFILE |