From owner-freebsd-bugs@FreeBSD.ORG Thu Feb 21 13:30:03 2008 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CAEBD16A400 for ; Thu, 21 Feb 2008 13:30:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id B5CCA13C442 for ; Thu, 21 Feb 2008 13:30:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m1LDU3l5051567 for ; Thu, 21 Feb 2008 13:30:03 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m1LDU3u4051564; Thu, 21 Feb 2008 13:30:03 GMT (envelope-from gnats) Date: Thu, 21 Feb 2008 13:30:03 GMT Message-Id: <200802211330.m1LDU3u4051564@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Jaakko Heinonen Cc: Subject: Re: bin/21089: vi silently corrupt open file on SIGINT when entering :wq in command mode X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Jaakko Heinonen List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 Feb 2008 13:30:03 -0000 The following reply was made to PR bin/21089; it has been noted by GNATS. From: Jaakko Heinonen To: Yar Tikhiy Cc: bug-followup@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@. ;-) ---------------------------- date: 2001/04/30 21:34:12; author: aymeric; state: Exp; lines: +20 -13 Now, ^C behaves just like (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, 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: /* 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, 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 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--