From a254bbde303c0f074caad34b20228d15db81272e Mon Sep 17 00:00:00 2001 From: edyfox Date: Thu, 5 Mar 2009 08:52:24 +0000 Subject: [PATCH] Merged from the latest developing branch. git-svn-id: https://vim.svn.sourceforge.net/svnroot/vim/trunk@1396 2a77ed30-b011-0410-a7ad-c7884a0aa172 --- src/config.h.in | 3 +++ src/configure.in | 1 + src/ex_docmd.c | 2 +- src/ex_getln.c | 25 +++++++++++++++++------ src/fileio.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++---- src/globals.h | 23 +++++++++++++++------ src/option.c | 30 ++++++++++++++++++++-------- src/os_unix.c | 54 ++++++++++++++++++++++++++++++++++++-------------- src/proto/ex_getln.pro | 1 + src/version.c | 10 ++++++++++ 10 files changed, 163 insertions(+), 40 deletions(-) diff --git a/src/config.h.in b/src/config.h.in index d1fb8d1b..900aef8d 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -50,6 +50,9 @@ /* Define to empty if the keyword does not work. */ #undef const +/* Define to empty if the keyword does not work. */ +#undef volatile + /* Define to `int' if doesn't define. */ #undef mode_t diff --git a/src/configure.in b/src/configure.in index b6c77da9..ff1bd0c9 100644 --- a/src/configure.in +++ b/src/configure.in @@ -2148,6 +2148,7 @@ fi dnl Checks for typedefs, structures, and compiler characteristics. AC_PROG_GCC_TRADITIONAL AC_C_CONST +AC_C_VOLATILE AC_TYPE_MODE_T AC_TYPE_OFF_T AC_TYPE_PID_T diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 60bbb5f8..c730d761 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -8792,7 +8792,7 @@ ex_mkrc(eap) else if (*dirnow != NUL && (ssop_flags & SSOP_CURDIR) && globaldir != NULL) { - if (mch_chdir((char *)globaldir) == OK) + if (mch_chdir((char *)globaldir) == 0) shorten_fnames(TRUE); } diff --git a/src/ex_getln.c b/src/ex_getln.c index e324e7ea..5cda65a0 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -2000,8 +2000,8 @@ text_locked_msg() #if defined(FEAT_AUTOCMD) || defined(PROTO) /* - * Check if "curbuf_lock" is set and return TRUE when it is and give an error - * message. + * Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is + * and give an error message. */ int curbuf_locked() @@ -2011,6 +2011,21 @@ curbuf_locked() EMSG(_("E788: Not allowed to edit another buffer now")); return TRUE; } + return allbuf_locked(); +} + +/* + * Check if "allbuf_lock" is set and return TRUE when it is and give an error + * message. + */ + int +allbuf_locked() +{ + if (allbuf_lock > 0) + { + EMSG(_("E811: Not allowed to change buffer information now")); + return TRUE; + } return FALSE; } #endif @@ -6047,9 +6062,7 @@ ex_window() # endif return K_IGNORE; } - cmdwin_type = ccline.cmdfirstc; - if (cmdwin_type == NUL) - cmdwin_type = '-'; + cmdwin_type = get_cmdline_type(); /* Create the command-line buffer empty. */ (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL); @@ -6073,7 +6086,7 @@ ex_window() /* Showing the prompt may have set need_wait_return, reset it. */ need_wait_return = FALSE; - histtype = hist_char2type(ccline.cmdfirstc); + histtype = hist_char2type(cmdwin_type); if (histtype == HIST_CMD || histtype == HIST_DEBUG) { if (p_wc == TAB) diff --git a/src/fileio.c b/src/fileio.c index 76d4b854..342cf590 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -69,7 +69,7 @@ static int apply_autocmds_exarg __ARGS((event_T event, char_u *fname, char_u *fn static int au_find_group __ARGS((char_u *name)); # define AUGROUP_DEFAULT -1 /* default autocmd group */ -# define AUGROUP_ERROR -2 /* errornouse autocmd group */ +# define AUGROUP_ERROR -2 /* erroneous autocmd group */ # define AUGROUP_ALL -3 /* all autocmd groups */ #endif @@ -144,7 +144,9 @@ static int get_mac_fio_flags __ARGS((char_u *ptr)); # endif #endif static int move_lines __ARGS((buf_T *frombuf, buf_T *tobuf)); - +#ifdef FEAT_AUTOCMD +static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name"); +#endif void filemess(buf, name, s, attr) @@ -295,6 +297,19 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags) int conv_restlen = 0; /* nr of bytes in conv_rest[] */ #endif +#ifdef FEAT_AUTOCMD + /* Remember the initial values of curbuf, curbuf->b_ffname and + * curbuf->b_fname to detect whether they are altered as a result of + * executing nasty autocommands. Also check if "fname" and "sfname" + * point to one of these values. */ + buf_T *old_curbuf = curbuf; + char_u *old_b_ffname = curbuf->b_ffname; + char_u *old_b_fname = curbuf->b_fname; + int using_b_ffname = (fname == curbuf->b_ffname) + || (sfname == curbuf->b_ffname); + int using_b_fname = (fname == curbuf->b_fname) + || (sfname == curbuf->b_fname); +#endif write_no_eol_lnum = 0; /* in case it was set by the previous read */ /* @@ -589,7 +604,21 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags) #ifdef FEAT_QUICKFIX if (!bt_dontwrite(curbuf)) #endif + { check_need_swap(newfile); +#ifdef FEAT_AUTOCMD + /* SwapExists autocommand may mess things up */ + if (curbuf != old_curbuf + || (using_b_ffname + && (old_b_ffname != curbuf->b_ffname)) + || (using_b_fname + && (old_b_fname != curbuf->b_fname))) + { + EMSG(_(e_auchangedbuf)); + return FAIL; + } +#endif + } if (dir_of_file_exists(fname)) filemess(curbuf, sfname, (char_u *)_("[New File]"), 0); else @@ -668,6 +697,17 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags) #endif { check_need_swap(newfile); +#ifdef FEAT_AUTOCMD + if (!read_stdin && (curbuf != old_curbuf + || (using_b_ffname && (old_b_ffname != curbuf->b_ffname)) + || (using_b_fname && (old_b_fname != curbuf->b_fname)))) + { + EMSG(_(e_auchangedbuf)); + if (!read_buffer) + close(fd); + return FAIL; + } +#endif #ifdef UNIX /* Set swap file protection bits after creating it. */ if (swap_mode > 0 && curbuf->b_ml.ml_mfp->mf_fname != NULL) @@ -698,7 +738,6 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags) { int m = msg_scroll; int n = msg_scrolled; - buf_T *old_curbuf = curbuf; /* * The file must be closed again, the autocommands may want to change @@ -740,8 +779,13 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags) /* * Don't allow the autocommands to change the current buffer. * Try to re-open the file. + * + * Don't allow the autocommands to change the buffer name either + * (cd for example) if it invalidates fname or sfname. */ if (!read_stdin && (curbuf != old_curbuf + || (using_b_ffname && (old_b_ffname != curbuf->b_ffname)) + || (using_b_fname && (old_b_fname != curbuf->b_fname)) || (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) < 0)) { --no_wait_return; @@ -6320,7 +6364,7 @@ check_timestamps(focus) if (!stuff_empty() || global_busy || !typebuf_typed() #ifdef FEAT_AUTOCMD - || autocmd_busy || curbuf_lock > 0 + || autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0 #endif ) need_check_timestamps = TRUE; /* check later */ @@ -6522,8 +6566,10 @@ buf_check_timestamp(buf, focus) set_vim_var_string(VV_FCS_REASON, (char_u *)reason, -1); set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", -1); # endif + ++allbuf_lock; n = apply_autocmds(EVENT_FILECHANGEDSHELL, buf->b_fname, buf->b_fname, FALSE, buf); + --allbuf_lock; busy = FALSE; if (n) { diff --git a/src/globals.h b/src/globals.h index 2125f4a1..548927af 100644 --- a/src/globals.h +++ b/src/globals.h @@ -482,8 +482,10 @@ EXTERN char *foreground_argument INIT(= NULL); /* * While executing external commands or in Ex mode, should not insert GUI * events in the input buffer: Set hold_gui_events to non-zero. + * + * volatile because it is used in signal handler sig_sysmouse(). */ -EXTERN int hold_gui_events INIT(= 0); +EXTERN volatile int hold_gui_events INIT(= 0); /* * When resizing the shell is postponed, remember the new size, and call @@ -597,7 +599,8 @@ EXTERN int exiting INIT(= FALSE); EXTERN int really_exiting INIT(= FALSE); /* TRUE when we are sure to exit, e.g., after * a deadly signal */ -EXTERN int full_screen INIT(= FALSE); +/* volatile because it is used in signal handler deathtrap(). */ +EXTERN volatile int full_screen INIT(= FALSE); /* TRUE when doing full-screen output * otherwise only writing some messages */ @@ -616,6 +619,11 @@ EXTERN int textlock INIT(= 0); EXTERN int curbuf_lock INIT(= 0); /* non-zero when the current buffer can't be * changed. Used for FileChangedRO. */ +EXTERN int allbuf_lock INIT(= 0); + /* non-zero when no buffer name can be + * changed, no buffer can be deleted and + * current directory can't be changed. + * Used for SwapExists et al. */ #endif #ifdef FEAT_EVAL # define HAVE_SANDBOX @@ -739,10 +747,12 @@ EXTERN JMP_BUF x_jump_env; */ EXTERN JMP_BUF lc_jump_env; /* argument to SETJMP() */ # ifdef SIGHASARG -EXTERN int lc_signal; /* catched signal number, 0 when no was signal - catched; used for mch_libcall() */ +/* volatile because it is used in signal handlers. */ +EXTERN volatile int lc_signal; /* caught signal number, 0 when no was signal + caught; used for mch_libcall() */ # endif -EXTERN int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */ +/* volatile because it is used in signal handler deathtrap(). */ +EXTERN volatile int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */ #endif #if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT) @@ -986,7 +996,8 @@ EXTERN int curscript INIT(= 0); /* index in scriptin[] */ EXTERN FILE *scriptout INIT(= NULL); /* stream to write script to */ EXTERN int read_cmd_fd INIT(= 0); /* fd to read commands from */ -EXTERN int got_int INIT(= FALSE); /* set to TRUE when interrupt +/* volatile because it is used in signal handler catch_sigint(). */ +EXTERN volatile int got_int INIT(= FALSE); /* set to TRUE when interrupt signal occurred */ #ifdef USE_TERM_CONSOLE EXTERN int term_console INIT(= FALSE); /* set to TRUE when console used */ diff --git a/src/option.c b/src/option.c index 87497ea6..d3912f83 100644 --- a/src/option.c +++ b/src/option.c @@ -5797,14 +5797,28 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf, /* load or unload key mapping tables */ errmsg = keymap_init(); - /* When successfully installed a new keymap switch on using it. */ - if (*curbuf->b_p_keymap != NUL && errmsg == NULL) - { - curbuf->b_p_iminsert = B_IMODE_LMAP; - if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT) - curbuf->b_p_imsearch = B_IMODE_LMAP; - set_iminsert_global(); - set_imsearch_global(); + if (errmsg == NULL) + { + if (*curbuf->b_p_keymap != NUL) + { + /* Installed a new keymap, switch on using it. */ + curbuf->b_p_iminsert = B_IMODE_LMAP; + if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT) + curbuf->b_p_imsearch = B_IMODE_LMAP; + } + else + { + /* Cleared the keymap, may reset 'iminsert' and 'imsearch'. */ + if (curbuf->b_p_iminsert == B_IMODE_LMAP) + curbuf->b_p_iminsert = B_IMODE_NONE; + if (curbuf->b_p_imsearch == B_IMODE_LMAP) + curbuf->b_p_imsearch = B_IMODE_USE_INSERT; + } + if ((opt_flags & OPT_LOCAL) == 0) + { + set_iminsert_global(); + set_imsearch_global(); + } # ifdef FEAT_WINDOWS status_redraw_curbuf(); # endif diff --git a/src/os_unix.c b/src/os_unix.c index 36872ad0..703b9323 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -181,7 +181,8 @@ static RETSIGTYPE catch_sigpwr __ARGS(SIGPROTOARG); && defined(FEAT_TITLE) && !defined(FEAT_GUI_GTK) # define SET_SIG_ALARM static RETSIGTYPE sig_alarm __ARGS(SIGPROTOARG); -static int sig_alarm_called; +/* volatile because it is used in signal handler sig_alarm(). */ +static volatile int sig_alarm_called; #endif static RETSIGTYPE deathtrap __ARGS(SIGPROTOARG); @@ -201,13 +202,16 @@ static int save_patterns __ARGS((int num_pat, char_u **pat, int *num_file, char_ # define SIG_ERR ((RETSIGTYPE (*)())-1) #endif -static int do_resize = FALSE; +/* volatile because it is used in signal handler sig_winch(). */ +static volatile int do_resize = FALSE; #ifndef __EMX__ static char_u *extra_shell_arg = NULL; static int show_shell_mess = TRUE; #endif -static int deadly_signal = 0; /* The signal we caught */ -static int in_mch_delay = FALSE; /* sleeping in mch_delay() */ +/* volatile because it is used in signal handler deathtrap(). */ +static volatile int deadly_signal = 0; /* The signal we caught */ +/* volatile because it is used in signal handler deathtrap(). */ +static volatile int in_mch_delay = FALSE; /* sleeping in mch_delay() */ static int curr_tmode = TMODE_COOK; /* contains current terminal mode */ @@ -802,7 +806,7 @@ init_signal_stack() #endif /* - * We need correct potatotypes for a signal function, otherwise mean compilers + * We need correct prototypes for a signal function, otherwise mean compilers * will barf when the second argument to signal() is ``wrong''. * Let me try it with a few tricky defines from my own osdef.h (jw). */ @@ -1068,13 +1072,18 @@ deathtrap SIGDEFARG(sigarg) SIGRETURN; } -#ifdef _REENTRANT +#if defined(_REENTRANT) && defined(SIGCONT) /* * On Solaris with multi-threading, suspending might not work immediately. * Catch the SIGCONT signal, which will be used as an indication whether the * suspending has been done or not. + * + * On Linux, signal is not always handled immediately either. + * See https://bugs.launchpad.net/bugs/291373 + * + * volatile because it is used in in signal handler sigcont_handler(). */ -static int sigcont_received; +static volatile int sigcont_received; static RETSIGTYPE sigcont_handler __ARGS(SIGPROTOARG); /* @@ -1118,15 +1127,28 @@ mch_suspend() } # endif -# ifdef _REENTRANT +# if defined(_REENTRANT) && defined(SIGCONT) sigcont_received = FALSE; # endif kill(0, SIGTSTP); /* send ourselves a STOP signal */ -# ifdef _REENTRANT - /* When we didn't suspend immediately in the kill(), do it now. Happens - * on multi-threaded Solaris. */ - if (!sigcont_received) - pause(); +# if defined(_REENTRANT) && defined(SIGCONT) + /* + * Wait for the SIGCONT signal to be handled. It generally happens + * immediately, but somehow not all the time. Do not call pause() + * because there would be race condition which would hang Vim if + * signal happened in between the test of sigcont_received and the + * call to pause(). If signal is not yet received, call sleep(0) + * to just yield CPU. Signal should then be received. If somehow + * it's still not received, sleep 1, 2, 3 ms. Don't bother waiting + * further if signal is not received after 1+2+3+4 ms (not expected + * to happen). + */ + { + long wait; + for (wait = 0; !sigcont_received && wait <= 3L; wait++) + /* Loop is not entered most of the time */ + mch_delay(wait, FALSE); + } # endif # ifdef FEAT_TITLE @@ -1175,7 +1197,7 @@ set_signals() #ifdef SIGTSTP signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL); #endif -#ifdef _REENTRANT +#if defined(_REENTRANT) && defined(SIGCONT) signal(SIGCONT, sigcont_handler); #endif @@ -1234,7 +1256,7 @@ catch_int_signal() reset_signals() { catch_signals(SIG_DFL, SIG_DFL); -#ifdef _REENTRANT +#if defined(_REENTRANT) && defined(SIGCONT) /* SIGCONT isn't in the list, because its default action is ignore */ signal(SIGCONT, SIG_DFL); #endif @@ -5899,7 +5921,9 @@ gpm_open() * we are going to suspend or starting an external process * so we shouldn't have problem with this */ +# ifdef SIGTSTP signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL); +# endif return 1; /* succeed */ } if (gpm_fd == -2) diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro index afbf6646..2750542f 100644 --- a/src/proto/ex_getln.pro +++ b/src/proto/ex_getln.pro @@ -4,6 +4,7 @@ char_u *getcmdline_prompt __ARGS((int firstc, char_u *prompt, int attr, int xp_c int text_locked __ARGS((void)); void text_locked_msg __ARGS((void)); int curbuf_locked __ARGS((void)); +int allbuf_locked __ARGS((void)); char_u *getexline __ARGS((int c, void *dummy, int indent)); char_u *getexmodeline __ARGS((int promptc, void *dummy, int indent)); int cmdline_overstrike __ARGS((void)); diff --git a/src/version.c b/src/version.c index 6877f67c..4388cd20 100644 --- a/src/version.c +++ b/src/version.c @@ -677,6 +677,16 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 132, +/**/ + 131, +/**/ + 130, +/**/ + 129, +/**/ + 128, +/**/ 127, /**/ 126, -- 2.11.4.GIT