bin/21089: vi silently corrupt open file on SIGINT when
entering :wq in command mode
Jaakko Heinonen
jh at saunalahti.fi
Thu Feb 21 13:30:03 UTC 2008
The following reply was made to PR bin/21089; it has been noted by GNATS.
From: Jaakko Heinonen <jh at saunalahti.fi>
To: Yar Tikhiy <yar at comp.chem.msu.su>
Cc: bug-followup at freebsd.org
Subject: Re: bin/21089: vi silently corrupt open file on SIGINT when
entering :wq in command mode
Date: Thu, 21 Feb 2008 15:23:34 +0200
--ew6BAiZeqk4r7MaW
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hi,
On 2008-02-15, Yar Tikhiy wrote:
> Upon a second thought, I'd rather follow the NetBSD way of dealing
> with this issue. Their way was hackish not for nothing: it had to
> deal with such complex cases of nvi text input as file name completion
> and former input replay.
I have obtained a patch series from NetBSD to fix the ^C and SIGWINCH
problems. The series contains also all other NetBSD bug fixes for v_txt.c
excluding fixes for compile warnings. Also OpeBSD seems to use the same
^C fix.
I have attached the patches including the original NetBSD cvs log
messages to this mail.
--
Jaakko
--ew6BAiZeqk4r7MaW
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="nvi-netbsd-v_ex.c-1.diff"
Obtained from: NetBSD
date: 2005/09/06 21:21:25; author: aymeric; state: Exp; lines: +6 -2
when reading an ex command within visual mode with v_tcmd(), check that
the termination value of v_tcmd() is alright. Abort the command otherwise.
Until the next commit in vi/v_txt.c, this is a noop.
diff -u -r1.11 -r1.12
--- v_ex.c 9 Apr 2002 01:47:35 -0000 1.11
+++ v_ex.c 6 Sep 2005 21:21:25 -0000 1.12
@@ -428,6 +428,10 @@ v_ex(sp, vp)
if (tp->term == TERM_BS)
break;
+ /* If the user changed their mind, return. */
+ if (tp->term != TERM_OK)
+ break;
+
/* Log the command. */
if (O_STR(sp, O_CEDIT) != NULL && v_ecl_log(sp, tp))
return (1);
--ew6BAiZeqk4r7MaW
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="nvi-netbsd-v_txt.c-1.diff"
Obtained from: NetBSD
date: 2005/09/06 21:30:36; author: aymeric; state: Exp; lines: +21 -10
Finally handle ^C the correct way. This indeed requires to separate the case
of text-recording input (usually text in insert mode) from the other cases
(e.g. ex command input). If recording, morph to escape key so that the input
is correctly finished for a potential replay; if not, simply bail out and
notify that something wrong occurs. Callers will cope.
The previous fix could make ^C sometimes produce a file completion
or a command edition, depending on the settings of the user.
I think this is the correct fix for since closed PR bin/11544 by pooka at . ;-)
----------------------------
date: 2001/04/30 21:34:12; author: aymeric; state: Exp; lines: +20 -13
Now, ^C behaves just like <ESC> (but for the ``Interrupt'' message).
It is consistent with what Solaris' vi and vim do.
This addresses PR #11544 by pooka.
Index: v_txt.c
===================================================================
RCS file: /home/ncvs/src/contrib/nvi/vi/v_txt.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 v_txt.c
--- v_txt.c 1 Nov 1996 06:45:33 -0000 1.1.1.1
+++ v_txt.c 18 Feb 2008 19:16:07 -0000
@@ -510,15 +510,6 @@ next: if (v_event_get(sp, evp, 0, ec_fla
case E_EOF:
F_SET(sp, SC_EXIT_FORCE);
return (1);
- case E_INTERRUPT:
- /*
- * !!!
- * Historically, <interrupt> exited the user from text input
- * mode or cancelled a colon command, and returned to command
- * mode. It also beeped the terminal, but that seems a bit
- * excessive.
- */
- goto k_escape;
case E_REPAINT:
if (vs_repaint(sp, &ev))
return (1);
@@ -526,10 +517,37 @@ next: if (v_event_get(sp, evp, 0, ec_fla
case E_WRESIZE:
/* <resize> interrupts the input mode. */
v_emsg(sp, NULL, VIM_WRESIZE);
- goto k_escape;
+ /* FALLTHROUGH */
default:
- v_event_err(sp, evp);
- goto k_escape;
+ if (evp->e_event != E_INTERRUPT && evp->e_event != E_WRESIZE)
+ v_event_err(sp, evp);
+ /*
+ * !!!
+ * Historically, <interrupt> exited the user from text input
+ * mode or cancelled a colon command, and returned to command
+ * mode. It also beeped the terminal, but that seems a bit
+ * excessive.
+ */
+ /*
+ * If we are recording, morph into <escape> key so that
+ * we can repeat the command safely: there is no way to
+ * invalidate the repetition of an instance of a command,
+ * which would be the alternative possibility.
+ * If we are not recording (most likely on the command line),
+ * simply discard the input and return to command mode
+ * so that an INTERRUPT doesn't become for example a file
+ * completion request. -aymeric
+ */
+ if (LF_ISSET(TXT_RECORD)) {
+ evp->e_event = E_CHARACTER;
+ evp->e_c = 033;
+ evp->e_flags = 0;
+ evp->e_value = K_ESCAPE;
+ break;
+ } else {
+ tp->term = TERM_ESC;
+ goto k_escape;
+ }
}
/*
--ew6BAiZeqk4r7MaW
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="nvi-netbsd-v_txt.c-2.diff"
Obtained from: NetBSD
date: 2001/08/20 21:44:57; author: aymeric; state: Exp; lines: +2 -2
Fix a bug present in nvi 1.79 where ^@ wouldn't behave as expected when
reading an ex command from vi.
diff -p -u -r1.5 -r1.6
--- v_txt.c 1 May 2001 16:46:12 -0000 1.5
+++ v_txt.c 20 Aug 2001 21:44:57 -0000 1.6
@@ -557,7 +557,7 @@ next: if (v_event_get(sp, evp, 0, ec_fla
* This was not documented as far as I know, and is a great test of vi
* clones.
*/
- if (rcol == 0 && !LF_ISSET(TXT_REPLAY) && evp->e_c == '\0') {
+ if (LF_ISSET(TXT_RECORD) && rcol == 0 && evp->e_c == '\0') {
if (vip->rep == NULL)
goto done;
--ew6BAiZeqk4r7MaW
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="nvi-netbsd-v_txt.c-3.diff"
Obtained from: NetBSD
date: 2003/06/06 08:06:47; author: aymeric; state: Exp; lines: +3 -2
branches: 1.11.4;
When an error occurs in v_txt(), leave input mode too.
Otherwise, (among other things) db_get() thinks it can re-use the TEXT buffers
when it's not true, leading to a crash because that TEXT buffer will be
released just before it is actually used to create a new one.
This fixes PR#21797.
diff -p -u -r1.10 -r1.11
--- v_txt.c 6 Jan 2003 20:30:41 -0000 1.10
+++ v_txt.c 6 Jun 2003 08:06:47 -0000 1.11
@@ -1474,6 +1474,7 @@ done: /* Leave input mode. */
err:
alloc_err:
+ F_CLR(sp, SC_TINPUT);
txt_err(sp, &sp->tiq);
return (1);
}
--ew6BAiZeqk4r7MaW
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="nvi-netbsd-v_txt.c-4.diff"
Obtained from: NetBSD
date: 2004/11/23 14:35:45; author: aymeric; state: Exp; lines: +3 -3
branches: 1.12.2;
Move a line of code which was "obviously" misplaced.
This fixes a core dump when auto-completing filenames and at least one of the
file names is larger than the screen width.
Bug report and fix by Peter Bex in PR#28382
diff -p -u -r1.11 -r1.12
--- v_txt.c 6 Jun 2003 08:06:47 -0000 1.11
+++ v_txt.c 23 Nov 2004 14:35:45 -0000 1.12
@@ -2235,8 +2235,8 @@ txt_fc_col(sp, argc, argv)
/* If the largest file name is too large, just print them. */
if (colwidth > sp->cols) {
- p = msg_print(sp, av[0]->bp + prefix, &nf);
for (ac = argc, av = argv; ac > 0; --ac, ++av) {
+ p = msg_print(sp, av[0]->bp + prefix, &nf);
(void)ex_printf(sp, "%s\n", p);
if (F_ISSET(gp, G_INTERRUPTED))
break;
--ew6BAiZeqk4r7MaW--
More information about the freebsd-bugs
mailing list