NetBSD Problem Report #50092
From www@NetBSD.org Sun Jul 26 09:59:58 2015
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
by mollari.NetBSD.org (Postfix) with ESMTPS id 34772A5864
for <gnats-bugs@gnats.NetBSD.org>; Sun, 26 Jul 2015 09:59:58 +0000 (UTC)
Message-Id: <20150726095956.85BEFA6552@mollari.NetBSD.org>
Date: Sun, 26 Jul 2015 09:59:56 +0000 (UTC)
From: okuyama@flex.phys.tohoku.ac.jp
Reply-To: okuyama@flex.phys.tohoku.ac.jp
To: gnats-bugs@NetBSD.org
Subject: huge memory leaks in vi(1) when changing screen size
X-Send-Pr-Version: www-1.0
>Number: 50092
>Category: bin
>Synopsis: huge memory leaks in vi(1) when changing screen size
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: bin-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Jul 26 10:00:00 +0000 2015
>Closed-Date: Tue May 31 06:10:57 +0000 2016
>Last-Modified: Sun Dec 18 06:40:00 +0000 2016
>Originator: Rin Okuyama
>Release: 7.99.20
>Organization:
Department of Physics, Tohoku University
>Environment:
NetBSD XXX 7.99.20 NetBSD 7.99.20 (XXX) #0: Sun Jul 19 18:42:21 JST 2015 root@XXX:XXX amd64
>Description:
The memory consumption of vi(1) grows order of MB by changing the
screen size.
>How-To-Repeat:
Execute vi(1), and change the screen size several times. You will
observe massive increase in the memory consumption.
>Fix:
This is caused by (I) vi(1) itself and underlying (II) curses and
(III) terminfo libraries.
(I) When the screen size is changed, vi(1) calls newterm(3) without
removing the established screen. For this problem, nvi2 [1,2] and
OpenBSD [3,4] provide patches, but unfortunately, we cannot apply
their patches for two reasons. First, they assume that
set_term(NULL) returns the current screen without any side effects.
This is *not* guaranteed by X/Open standards [5], and causes null
pointer dereferences for our implementation [6]. Second, their
patches break vertically splitted windows [2]. I've prepared an
alternative patch derived from nvi-1.79nb16 [7]: use setterm(3) and
resizeterm(3) instead of newterm(3) for reinitializing the screen.
[1] https://github.com/lichray/nvi2/commit/a8c38480adb030a05bbb2aafec6067dd65d8c2eb
[2] https://github.com/lichray/nvi2/commit/879d2ad6dd4a4343eb0a588ebfe637e1c9845bc4
[3] http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/vi/cl/cl_screen.c#rev1.23
[4] http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/vi/cl/cl_term.c#rev1.20
[5] http://pubs.opengroup.org/onlinepubs/7908799/xcurses/set_term.html
[6] http://nxr.netbsd.org/source/xref/src/lib/libcurses/screen.c#46
[7] http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.bin/vi/cl/Attic/cl_screen.c#rev1.7
(II) _cursesi_setterm() does not delete the established terminal
before calling ti_setupterm(3). I've also found other small memory
leaks.
(III) _ti_readterm() uses [cm]alloc(3) without checking whether
buffers have been allocated or not. I've also addressed other small
memory leaks.
After applying this patch, the memory consumption of vi(1) grows
order of 10KB for the first time you change the screen size; there
are possibly other memory leaks. However, it saturates by a few
times of resizing and does not increases infinitely.
I shall add one more comment. If you change the screen size rapidly,
sometimes you get error messages and additional memory consumption.
I guess that this is because a succeeding SIGWINCH interrupts the
reinitialization of screen due to a preceding SIGWINCH. It would be
better to neglect SIGWINCH during the (re)initialization of curses
screen. I'd like to hear your opinion.
--- src/external/bsd/nvi/Makefile.inc.orig 2015-07-26 01:29:59.000000000 +0900
+++ src/external/bsd/nvi/Makefile.inc 2015-07-26 01:30:05.000000000 +0900
@@ -7,4 +7,4 @@
BINDIR=/usr/bin
CWARNFLAGS.clang+= -Wno-error=unused-const-variable
-VERSION=1.81.6-2013-11-20
+VERSION=1.81.6-2013-11-20nb1
--- src/external/bsd/nvi/dist/cl/cl_screen.c.orig 2015-07-25 08:26:48.000000000 +0900
+++ src/external/bsd/nvi/dist/cl/cl_screen.c 2015-07-25 11:50:37.000000000 +0900
@@ -189,6 +189,7 @@
cl_vi_init(SCR *sp)
{
CL_PRIVATE *clp;
+ static int newterm_done = 0;
char *o_cols, *o_lines, *o_term;
const char *ttype;
@@ -249,13 +250,17 @@
* have to specify the terminal type.
*/
errno = 0;
- if (newterm(__UNCONST(ttype), stdout, stdin) == NULL) {
+ if (!newterm_done && newterm(__UNCONST(ttype), stdout, stdin) == NULL) {
if (errno)
msgq(sp, M_SYSERR, "%s", ttype);
else
msgq(sp, M_ERR, "%s: unknown terminal type", ttype);
return (1);
+ } else if (newterm_done) {
+ setterm(__UNCONST(ttype));
+ resizeterm(O_VAL(sp, O_LINES), O_VAL(sp, O_COLUMNS));
}
+ newterm_done = 1;
if (o_term == NULL)
cl_unsetenv(sp, "TERM");
--- src/external/bsd/nvi/dist/cl/cl_term.c.orig 2015-07-25 08:31:16.000000000 +0900
+++ src/external/bsd/nvi/dist/cl/cl_term.c 2015-07-26 01:20:08.000000000 +0900
@@ -417,7 +417,6 @@
*rowp = row;
if (colp != NULL)
*colp = col;
- resizeterm(row, col);
return (0);
}
--- src/lib/libcurses/screen.c.orig 2015-07-25 09:11:42.000000000 +0900
+++ src/lib/libcurses/screen.c 2015-07-26 00:06:12.000000000 +0900
@@ -207,6 +207,9 @@
return new_screen;
error_exit:
+ if (new_screen->term != NULL)
+ (void)del_curterm(new_screen->term);
+ free(new_screen->unget_list);
free(new_screen);
return NULL;
}
@@ -239,7 +242,7 @@
_cursesi_free_keymap(screen->base_keymap);
free(screen->stdbuf);
- screen->stdbuf = NULL;
+ free(screen->unget_list);
if (_cursesi_screen == screen)
_cursesi_screen = NULL;
free(screen);
--- src/lib/libcurses/setterm.c.orig 2015-07-25 09:04:58.000000000 +0900
+++ src/lib/libcurses/setterm.c 2015-07-25 09:25:16.000000000 +0900
@@ -66,6 +66,8 @@
struct winsize win;
char *p;
+ if (screen->term != NULL)
+ (void)del_curterm(screen->term);
if (type[0] == '\0')
type = "xx";
unknown = 0;
--- src/lib/libterminfo/compile.c.orig 2015-07-25 22:09:17.000000000 +0900
+++ src/lib/libterminfo/compile.c 2015-07-25 22:09:58.000000000 +0900
@@ -653,10 +653,10 @@
free(tic->name);
free(tic->alias);
free(tic->desc);
- free(tic->extras.buf);
free(tic->flags.buf);
free(tic->nums.buf);
free(tic->strs.buf);
+ free(tic->extras.buf);
free(tic);
}
}
--- src/lib/libterminfo/curterm.c.orig 2015-07-25 09:13:21.000000000 +0900
+++ src/lib/libterminfo/curterm.c 2015-07-25 22:03:18.000000000 +0900
@@ -134,11 +134,12 @@
if (oterm == NULL)
return ERR;
- free(oterm->_area);
- free(oterm->strs);
- free(oterm->nums);
free(oterm->flags);
+ free(oterm->nums);
+ free(oterm->strs);
+ free(oterm->_area);
free(oterm->_userdefs);
+ free(oterm->_buf);
free(oterm);
return OK;
}
--- src/lib/libterminfo/term.c.orig 2015-07-25 22:17:02.000000000 +0900
+++ src/lib/libterminfo/term.c 2015-07-26 00:26:29.000000000 +0900
@@ -68,20 +68,30 @@
return -1;
}
- term->flags = calloc(TIFLAGMAX + 1, sizeof(char));
- if (term->flags == NULL)
- return -1;
- term->nums = malloc((TINUMMAX + 1) * sizeof(short));
- if (term->nums == NULL)
- return -1;
+ if (term->flags == NULL) {
+ term->flags = calloc(TIFLAGMAX + 1, sizeof(char));
+ if (term->flags == NULL)
+ return -1;
+ } else
+ memset(term->flags, 0, (TIFLAGMAX + 1) * sizeof(char));
+ if (term->nums == NULL) {
+ term->nums = malloc((TINUMMAX + 1) * sizeof(short));
+ if (term->nums == NULL)
+ return -1;
+ }
memset(term->nums, (short)-1, (TINUMMAX + 1) * sizeof(short));
- term->strs = calloc(TISTRMAX + 1, sizeof(char *));
- if (term->strs == NULL)
- return -1;
+ if (term->strs == NULL) {
+ term->strs = calloc(TISTRMAX + 1, sizeof(char *));
+ if (term->strs == NULL)
+ return -1;
+ } else
+ memset(term->strs, 0, (TISTRMAX + 1) * sizeof(char *));
term->_arealen = caplen;
- term->_area = malloc(term->_arealen);
- if (term->_area == NULL)
- return -1;
+ if (term->_area == NULL) {
+ term->_area = malloc(term->_arealen);
+ if (term->_area == NULL)
+ return -1;
+ }
memcpy(term->_area, cap, term->_arealen);
cap = term->_area;
@@ -352,11 +362,11 @@
e = strdup(e); /* So we don't destroy env */
if (e == NULL)
tic = NULL;
- else
+ else {
tic = _ti_compile(e, TIC_WARNING |
TIC_ALIAS | TIC_DESCRIPTION | TIC_EXTRA);
- if (c == NULL && e != NULL)
free(e);
+ }
if (tic != NULL && ticcmp(tic, name) == 0) {
len = _ti_flatten(&f, tic);
if (len != -1) {
--- src/lib/libterminfo/termcap.c.orig 2015-07-25 22:38:49.000000000 +0900
+++ src/lib/libterminfo/termcap.c 2015-07-25 22:39:29.000000000 +0900
@@ -553,8 +553,11 @@
else
len += rl;
p = realloc(info, len);
- if (p == NULL)
+ if (p == NULL) {
+ if (fv)
+ free(val);
return NULL;
+ }
info = p;
}
>Release-Note:
>Audit-Trail:
From: Julian Coleman <jdc@coris.org.uk>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/50092: huge memory leaks in vi(1) when changing screen size
Date: Mon, 27 Jul 2015 12:21:17 +0100
Hi,
> I shall add one more comment. If you change the screen size rapidly,
> sometimes you get error messages and additional memory consumption.
> I guess that this is because a succeeding SIGWINCH interrupts the
> reinitialization of screen due to a preceding SIGWINCH. It would be
> better to neglect SIGWINCH during the (re)initialization of curses
> screen. I'd like to hear your opinion.
If we resize many times, we probably only care about the final size. So,
we really could ignore any apart from the last resize. However, if we're
already processing a resize, we should finish processing so that everthing
is consistent (i.e. not interrupt the current resize).
I wonder if we can just save the new size when we're already processing and
check at the end of the current processing if a new (and different) size is
saved? Then we would re-run the resize with the new saved size.
Regards,
J
--
My other computer runs NetBSD too - http://www.netbsd.org/
From: Rin Okuyama <okuyama@flex.phys.tohoku.ac.jp>
To: Julian Coleman <jdc@coris.org.uk>, gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/50092: huge memory leaks in vi(1) when changing screen size
Date: Tue, 28 Jul 2015 00:10:55 +0900
Thank you for your comment.
> If we resize many times, we probably only care about the final size. So,
> we really could ignore any apart from the last resize. However, if we're
> already processing a resize, we should finish processing so that everthing
> is consistent (i.e. not interrupt the current resize).
Exactly.
> I wonder if we can just save the new size when we're already processing and
> check at the end of the current processing if a new (and different) size is
> saved? Then we would re-run the resize with the new saved size.
I think that your suggestion is a right way to deal with the problem.
Theoretically, we can do so by switching signal handlers appropriately.
Let me think for a while about actual implementation.
Except this problem, my patch improves the situation. At least, vi no
longer wastes MB of memory. Other commands using terminfo/curses, less,
more, rogue, tetris, and sysinst work fine. Could anyone please review
and commit it?
Rin
From: Rin Okuyama <okuyama@flex.phys.tohoku.ac.jp>
To: Julian Coleman <jdc@coris.org.uk>, gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/50092: huge memory leaks in vi(1) when changing screen size
Date: Mon, 3 Aug 2015 10:56:19 +0900
This is a multi-part message in MIME format.
--------------070700000004050800030903
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Hi,
> If we resize many times, we probably only care about the final size. So,
> we really could ignore any apart from the last resize. However, if we're
> already processing a resize, we should finish processing so that everthing
> is consistent (i.e. not interrupt the current resize).
>
> I wonder if we can just save the new size when we're already processing and
> check at the end of the current processing if a new (and different) size is
> saved? Then we would re-run the resize with the new saved size.
I examined the problem with the continuous screen size change in detail,
using icewm/xterm on a slow virtual machine.
(a) The original NetBSD version sometimes aborts with message
"ex/vi: Error: screen: Interrupted system call". This is because
newterm(3) is interrupted by SIGWINCH. This problem was reported for
nvi-1.79 as bin/25849:
http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=25849
The fix is merged to NetBSD at that time, however it seems to be
overlooked when nvi-1.86 was imported.
(b) The patched version attached to my PR does not abort as it is based
on the fix to bin/25849. However, it sometimes issues error messages
like "Error: move: l(48 + 0) c(0 + 0)". This is because setterm(3) or
resizeterm(3) are interrupted by SIGWINCH and the screen initialization
fails. The fix to bin/25849 is not sufficient; the reason why it does
not abort is simply because it does not check return values of
setterm(3) and resizeterm(3).
To address the problem, I modified the patch as follows.
(1) During initialization of the screen, block signals to make sure that
curses/terminfo routines are not interrupted.
(2) In the signal handler for SIGWINCH, wait up to 1/10 seconds for a
succeeding SIGWINCH received. This approximately realizes your
suggestion.
In addition, I made following changes.
(3) Use delscreen(3) and newterm(3) for reinitialization of the screen,
instead of setterm(3) and resizeterm(3), that are BSD/ncurses extension
to the X/Open standards. This also resolves a memory leak when
switching to ex-mode from vi-mode.
(4) Delete the terminfo cur_term when we enter to vi-mode. We must
initialize it in main() for processing .exrc or EXINIT. However, in
vi-mode, it is overwritten by newterm(3), which results in a memory
leak.
(5) In ex-mode, use del_curterm(3) and setupterm(3) to update the
terminfo database when the terminal type is changed. In the original
version, we forget this before retrieving the terminfo entries.
For memory leaks in libcurses/terminfo, I will send another PRs if
necessary.
Thanks,
Rin
--------------070700000004050800030903
Content-Type: text/plain; charset=UTF-8; x-mac-type="0"; x-mac-creator="0";
name="nvi.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="nvi.patch"
Index: src/external/bsd/nvi/Makefile.inc
diff -u src/external/bsd/nvi/Makefile.inc:1.1.1.1 src/external/bsd/nvi/Makefile.inc:1.4
--- src/external/bsd/nvi/Makefile.inc:1.1.1.1 Fri Jul 31 20:44:59 2015
+++ src/external/bsd/nvi/Makefile.inc Mon Aug 3 00:21:50 2015
@@ -7,4 +7,4 @@
BINDIR=/usr/bin
CWARNFLAGS.clang+= -Wno-error=unused-const-variable
-VERSION=1.81.6-2013-11-20
+VERSION=1.81.6-2013-11-20nb1
Index: src/external/bsd/nvi/dist/cl/cl.h
diff -u src/external/bsd/nvi/dist/cl/cl.h:1.1.1.1 src/external/bsd/nvi/dist/cl/cl.h:1.2
--- src/external/bsd/nvi/dist/cl/cl.h:1.1.1.1 Fri Jul 31 20:44:59 2015
+++ src/external/bsd/nvi/dist/cl/cl.h Sat Aug 1 18:24:49 2015
@@ -42,6 +42,8 @@
struct termios ex_enter;/* Terminal values to enter ex. */
struct termios vi_enter;/* Terminal values to enter vi. */
+ SCREEN *screen; /* Curses screen. */
+
char *el; /* Clear to EOL terminal string. */
char *cup; /* Cursor movement terminal string. */
char *cuu1; /* Cursor up terminal string. */
@@ -77,6 +79,8 @@
#define CL_SIGTERM 0x0100 /* SIGTERM arrived. */
#define CL_SIGWINCH 0x0200 /* SIGWINCH arrived. */
#define CL_STDIN_TTY 0x0400 /* Talking to a terminal. */
+#define CL_SETUPTERM 0x0800 /* Terminal initialized. */
+#define CL_CHANGE_TERM 0x1000 /* Terminal changed. */
u_int32_t flags;
} CL_PRIVATE;
Index: src/external/bsd/nvi/dist/cl/cl_main.c
diff -u src/external/bsd/nvi/dist/cl/cl_main.c:1.1.1.1 src/external/bsd/nvi/dist/cl/cl_main.c:1.4
--- src/external/bsd/nvi/dist/cl/cl_main.c:1.1.1.1 Fri Jul 31 20:44:59 2015
+++ src/external/bsd/nvi/dist/cl/cl_main.c Mon Aug 3 00:21:14 2015
@@ -109,6 +109,7 @@
ttype = "unknown";
}
term_init(gp->progname, ttype);
+ F_SET(clp, CL_SETUPTERM);
/* Add the terminal type to the global structure. */
if ((OG_D_STR(gp, GO_TERM) =
@@ -292,6 +293,22 @@
h_winch(int signo)
{
GLOBAL_CLP;
+ sigset_t sigset;
+ struct timespec timeout;
+
+ /*
+ * Some window managers continuously change the screen size of terminal
+ * emulators, by which a lot of SIGWINCH signals are to be received. In
+ * such a case, we only need to respond the final signal; the remaining
+ * signals are meaningless. Thus, we wait here up to 1/10 of a second
+ * for a succeeding signal received.
+ */
+ (void)sigemptyset(&sigset);
+ (void)sigaddset(&sigset, SIGWINCH);
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = 100 * 1000 * 1000;
+ while (sigtimedwait(&sigset, NULL, &timeout) != -1)
+ continue;
F_SET(clp, CL_SIGWINCH);
}
Index: src/external/bsd/nvi/dist/cl/cl_screen.c
diff -u src/external/bsd/nvi/dist/cl/cl_screen.c:1.1.1.1 src/external/bsd/nvi/dist/cl/cl_screen.c:1.5
--- src/external/bsd/nvi/dist/cl/cl_screen.c:1.1.1.1 Fri Jul 31 20:44:59 2015
+++ src/external/bsd/nvi/dist/cl/cl_screen.c Mon Aug 3 00:29:51 2015
@@ -34,6 +34,10 @@
#include "../common/common.h"
#include "cl.h"
+#ifndef BLOCK_SIGNALS
+extern sigset_t __sigblockset;
+#endif
+
static int cl_ex_end __P((GS *));
static int cl_ex_init __P((SCR *));
static void cl_freecap __P((CL_PRIVATE *));
@@ -53,26 +57,37 @@
CL_PRIVATE *clp;
WINDOW *win;
GS *gp;
+ int ret;
gp = sp->gp;
clp = CLP(sp);
win = CLSP(sp) ? CLSP(sp) : stdscr;
+ ret = 0;
+
+ /*
+ * During initialization of the screen, block signals to make sure that
+ * curses/terminfo routines are not interrupted.
+ */
+ (void)sigprocmask(SIG_BLOCK, &__sigblockset, NULL);
+
/* See if the current information is incorrect. */
if (F_ISSET(gp, G_SRESTART)) {
if (CLSP(sp)) {
delwin(CLSP(sp));
sp->cl_private = NULL;
}
- if (cl_quit(gp))
- return (1);
+ if (cl_quit(gp)) {
+ ret = 1;
+ goto end;
+ }
F_CLR(gp, G_SRESTART);
}
/* See if we're already in the right mode. */
if ((LF_ISSET(SC_EX) && F_ISSET(sp, SC_SCR_EX)) ||
(LF_ISSET(SC_VI) && F_ISSET(sp, SC_SCR_VI)))
- return (0);
+ goto end;
/*
* Fake leaving ex mode.
@@ -109,8 +124,10 @@
/* Enter the requested mode. */
if (LF_ISSET(SC_EX)) {
- if (cl_ex_init(sp))
- return (1);
+ if (cl_ex_init(sp)) {
+ ret = 1;
+ goto end;
+ }
F_SET(clp, CL_IN_EX | CL_SCR_EX_INIT);
/*
@@ -121,12 +138,17 @@
tputs(tgoto(clp->cup,
0, O_VAL(sp, O_LINES) - 1), 1, cl_putchar);
} else {
- if (cl_vi_init(sp))
- return (1);
+ if (cl_vi_init(sp)) {
+ ret = 1;
+ goto end;
+ }
F_CLR(clp, CL_IN_EX);
F_SET(clp, CL_SCR_VI_INIT);
}
- return (0);
+end:
+ /* Unblock signals. */
+ (void)sigprocmask(SIG_UNBLOCK, &__sigblockset, NULL);
+ return ret;
}
/*
@@ -234,10 +256,14 @@
o_cols = getenv("COLUMNS");
cl_putenv(sp, "COLUMNS", NULL, (u_long)O_VAL(sp, O_COLUMNS));
+ /* Delete cur_term if exists. */
+ if (F_ISSET(clp, CL_SETUPTERM)) {
+ if (del_curterm(cur_term))
+ return (1);
+ F_CLR(clp, CL_SETUPTERM);
+ }
+
/*
- * We don't care about the SCREEN reference returned by newterm, we
- * never have more than one SCREEN at a time.
- *
* XXX
* The SunOS initscr() can't be called twice. Don't even think about
* using it. It fails in subtle ways (e.g. select(2) on fileno(stdin)
@@ -249,7 +275,7 @@
* have to specify the terminal type.
*/
errno = 0;
- if (newterm(__UNCONST(ttype), stdout, stdin) == NULL) {
+ if ((clp->screen = newterm(__UNCONST(ttype), stdout, stdin)) == NULL) {
if (errno)
msgq(sp, M_SYSERR, "%s", ttype);
else
@@ -374,8 +400,6 @@
fast: /* Set the terminal modes. */
if (tcsetattr(STDIN_FILENO, TCSASOFT | TCSADRAIN, &clp->vi_enter)) {
- if (errno == EINTR)
- goto fast;
msgq(sp, M_SYSERR, "tcsetattr");
err: (void)cl_vi_end(sp->gp);
return (1);
@@ -416,6 +440,9 @@
/* End curses window. */
(void)endwin();
+ /* Delete curses screen. */
+ delscreen(clp->screen);
+
/*
* XXX
* The screen TE sequence just got sent. See the comment in
@@ -434,6 +461,8 @@
cl_ex_init(SCR *sp)
{
CL_PRIVATE *clp;
+ int error;
+ const char *ttype;
clp = CLP(sp);
@@ -445,6 +474,22 @@
if (!F_ISSET(clp, CL_STDIN_TTY))
return (0);
+ if (F_ISSET(clp, CL_CHANGE_TERM)) {
+ if (F_ISSET(clp, CL_SETUPTERM) && del_curterm(cur_term))
+ return (1);
+ F_CLR(clp, CL_SETUPTERM | CL_CHANGE_TERM);
+ }
+
+ if (!F_ISSET(clp, CL_SETUPTERM)) {
+ /* We'll need a terminal type. */
+ if (opts_empty(sp, O_TERM, 0))
+ return (1);
+ ttype = O_STR(sp, O_TERM);
+ (void)setupterm(ttype, STDOUT_FILENO, &error);
+ if (error == 0 || error == -1)
+ return (1);
+ }
+
/* Get the ex termcap/terminfo strings. */
(void)cl_getcap(sp, "cup", &clp->cup);
(void)cl_getcap(sp, "smso", &clp->smso);
Index: src/external/bsd/nvi/dist/cl/cl_term.c
diff -u src/external/bsd/nvi/dist/cl/cl_term.c:1.1.1.1 src/external/bsd/nvi/dist/cl/cl_term.c:1.3
--- src/external/bsd/nvi/dist/cl/cl_term.c:1.1.1.1 Fri Jul 31 20:44:59 2015
+++ src/external/bsd/nvi/dist/cl/cl_term.c Sat Aug 1 18:24:49 2015
@@ -268,9 +268,12 @@
clp = CLP(sp);
switch (opt) {
+ case O_TERM:
+ if (F_ISSET(sp, SC_SCR_EX))
+ F_SET(clp, CL_CHANGE_TERM);
+ /* FALLTHROUGH */
case O_COLUMNS:
case O_LINES:
- case O_TERM:
/*
* Changing the columns, lines or terminal require that
* we restart the screen.
@@ -417,7 +420,6 @@
*rowp = row;
if (colp != NULL)
*colp = col;
- resizeterm(row, col);
return (0);
}
--------------070700000004050800030903--
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/50092 CVS commit: src/lib/libcurses
Date: Mon, 23 Nov 2015 20:59:33 -0500
Module Name: src
Committed By: christos
Date: Tue Nov 24 01:59:33 UTC 2015
Modified Files:
src/lib/libcurses: setterm.c
Log Message:
PR/50092: don't leak screen on multiple setterms.
To generate a diff of this commit:
cvs rdiff -u -r1.52 -r1.53 src/lib/libcurses/setterm.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/50092 CVS commit: src/lib/libterminfo
Date: Wed, 25 Nov 2015 13:38:22 -0500
Module Name: src
Committed By: christos
Date: Wed Nov 25 18:38:22 UTC 2015
Modified Files:
src/lib/libterminfo: curterm.c
Log Message:
PR/50092: Fix memory leak.
To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/lib/libterminfo/curterm.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/50092 CVS commit: src/lib/libterminfo
Date: Wed, 25 Nov 2015 13:46:24 -0500
Module Name: src
Committed By: christos
Date: Wed Nov 25 18:46:24 UTC 2015
Modified Files:
src/lib/libterminfo: termcap.c
Log Message:
PR/50092: Rin Okuyama: Fix memory leak.
To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/lib/libterminfo/termcap.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/50092 CVS commit: src/lib/libterminfo
Date: Wed, 25 Nov 2015 14:13:50 -0500
Module Name: src
Committed By: christos
Date: Wed Nov 25 19:13:49 UTC 2015
Modified Files:
src/lib/libterminfo: term.c
Log Message:
From PR/50092:
- handle calling _ti_readterm with an existing initialized terminal
- simplify free code
Also:
- fix an inconsistency in userdefs count computation
To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/lib/libterminfo/term.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/50092 CVS commit: src/external/bsd/nvi
Date: Wed, 25 Nov 2015 15:25:20 -0500
Module Name: src
Committed By: christos
Date: Wed Nov 25 20:25:20 UTC 2015
Modified Files:
src/external/bsd/nvi: Makefile.inc
src/external/bsd/nvi/dist/cl: cl.h cl_main.c cl_screen.c cl_term.c
Log Message:
PR/50092: Rin Okuyama: Fix memory leaks in vi when resizing.
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/external/bsd/nvi/Makefile.inc
cvs rdiff -u -r1.2 -r1.3 src/external/bsd/nvi/dist/cl/cl.h
cvs rdiff -u -r1.4 -r1.5 src/external/bsd/nvi/dist/cl/cl_main.c \
src/external/bsd/nvi/dist/cl/cl_screen.c \
src/external/bsd/nvi/dist/cl/cl_term.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Rin Okuyama <okuyama@flex.phys.tohoku.ac.jp>
To: gnats-bugs@NetBSD.org, christos@netbsd.org
Cc:
Subject: Re: PR/50092 CVS commit: src/external/bsd/nvi
Date: Thu, 26 Nov 2015 08:34:02 +0900
Thank you for your improvement and commitment of my patches. I shall
make two comments.
(1) For _ti_readbuf() in libterminfo, cap should always be copied into
the buffer; caplen can accidentally be same as before.
======
--- src/lib/libterminfo/term.c.orig 2015-11-26 08:14:56.000000000 +0900
+++ src/lib/libterminfo/term.c 2015-11-26 08:15:33.000000000 +0900
@@ -100,8 +100,8 @@
term->_area = realloc(term->_area, term->_arealen);
if (term->_area == NULL)
return -1;
- memcpy(term->_area, cap, term->_arealen);
}
+ memcpy(term->_area, cap, term->_arealen);
cap = term->_area;
len = le16dec(cap);
======
(2) For libcurses, screen->unget_list and screen->term should be freed
when we delete screen.
======
--- src/lib/libcurses/screen.c.orig 2015-07-25 09:11:42.000000000 +0900
+++ src/lib/libcurses/screen.c 2015-07-26 00:06:12.000000000 +0900
@@ -207,6 +207,9 @@
return new_screen;
error_exit:
+ if (new_screen->term != NULL)
+ (void)del_curterm(new_screen->term);
+ free(new_screen->unget_list);
free(new_screen);
return NULL;
}
@@ -239,7 +242,7 @@
_cursesi_free_keymap(screen->base_keymap);
free(screen->stdbuf);
- screen->stdbuf = NULL;
+ free(screen->unget_list);
if (_cursesi_screen == screen)
_cursesi_screen = NULL;
free(screen);
======
Thanks,
Rin
From: christos@zoulas.com (Christos Zoulas)
To: Rin Okuyama <okuyama@flex.phys.tohoku.ac.jp>, gnats-bugs@NetBSD.org
Cc:
Subject: Re: PR/50092 CVS commit: src/external/bsd/nvi
Date: Wed, 25 Nov 2015 20:05:30 -0500
On Nov 26, 8:34am, okuyama@flex.phys.tohoku.ac.jp (Rin Okuyama) wrote:
-- Subject: Re: PR/50092 CVS commit: src/external/bsd/nvi
| Thank you for your improvement and commitment of my patches. I shall
| make two comments.
Thank you again! Applied.
christos
From: Rin Okuyama <okuyama@flex.phys.tohoku.ac.jp>
To: gnats-bugs@NetBSD.org, christos@netbsd.org
Cc:
Subject: Re: PR/50092 CVS commit: src/external/bsd/nvi
Date: Thu, 26 Nov 2015 11:40:47 +0900
Fix confirmed. Thank you very much!
From: christos@zoulas.com (Christos Zoulas)
To: Rin Okuyama <okuyama@flex.phys.tohoku.ac.jp>, gnats-bugs@NetBSD.org
Cc:
Subject: Re: PR/50092 CVS commit: src/external/bsd/nvi
Date: Thu, 26 Nov 2015 11:19:48 -0500
On Nov 26, 11:40am, okuyama@flex.phys.tohoku.ac.jp (Rin Okuyama) wrote:
-- Subject: Re: PR/50092 CVS commit: src/external/bsd/nvi
| Fix confirmed. Thank you very much!
Thank you for the patch!
christos
State-Changed-From-To: open->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Tue, 31 May 2016 06:10:57 +0000
State-Changed-Why:
All committed as of back in November.
From: "Soren Jacobsen" <snj@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/50092 CVS commit: [netbsd-7] src/lib/libterminfo
Date: Mon, 12 Dec 2016 07:37:53 +0000
Module Name: src
Committed By: snj
Date: Mon Dec 12 07:37:53 UTC 2016
Modified Files:
src/lib/libterminfo [netbsd-7]: curterm.c term.c termcap.c terminfo.3
tparm.c
Log Message:
Pull up following revision(s) (requested by riastradh in ticket #1307):
lib/libterminfo/curterm.c: revisions 1.11, 1.12
lib/libterminfo/term.c: revisions 1.18-1.20
lib/libterminfo/termcap.c: revisions 1.18, 1.19
lib/libterminfo/terminfo.3: revision 1.13
lib/libterminfo/tparm.c: revision 1.16
terminfo.3: fix ti_puts prototype
--
PR/50092: Fix memory leak.
--
PR/50092: Rin Okuyama: Fix memory leak.
--
We have the max length; use snprintf.
--
From PR/50092:
- handle calling _ti_readterm with an existing initialized terminal
- simplify free code
Also:
- fix an inconsistency in userdefs count computation
--
Always copy the area buffer, even when the length was the same
(from Rin Okuyama)
--
- if we are freeing cur_term, set it to NULL.
- preserve and free "last" properly.
--
off-by-one in memcpy. Found by ASAN (Carsten Kunze)
To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.10.4.1 src/lib/libterminfo/curterm.c
cvs rdiff -u -r1.17 -r1.17.6.1 src/lib/libterminfo/term.c
cvs rdiff -u -r1.17 -r1.17.18.1 src/lib/libterminfo/termcap.c
cvs rdiff -u -r1.12 -r1.12.4.1 src/lib/libterminfo/terminfo.3
cvs rdiff -u -r1.15 -r1.15.6.1 src/lib/libterminfo/tparm.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Soren Jacobsen" <snj@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/50092 CVS commit: [netbsd-7] src/external/bsd/nvi
Date: Sun, 18 Dec 2016 06:37:31 +0000
Module Name: src
Committed By: snj
Date: Sun Dec 18 06:37:30 UTC 2016
Modified Files:
src/external/bsd/nvi [netbsd-7]: Makefile.inc
src/external/bsd/nvi/dist/cl [netbsd-7]: cl.h cl_main.c cl_screen.c
cl_term.c
src/external/bsd/nvi/dist/common [netbsd-7]: key.h vi_db1.c
src/external/bsd/nvi/dist/docs/vi.man [netbsd-7]: vi.1
src/external/bsd/nvi/dist/ex [netbsd-7]: ex_map.c ex_script.c
src/external/bsd/nvi/usr.bin/nvi [netbsd-7]: Makefile
Log Message:
Pull up following revision(s) (requested by riastradh in ticket #1312):
external/bsd/nvi/Makefile.inc: revisions 1.2-1.4
external/bsd/nvi/dist/cl/cl.h: revision 1.3
external/bsd/nvi/dist/cl/cl_main.c: revision 1.5
external/bsd/nvi/dist/cl/cl_screen.c: revision 1.5
external/bsd/nvi/dist/cl/cl_term.c: revision 1.5
external/bsd/nvi/dist/common/key.h: revision 1.3
external/bsd/nvi/dist/common/vi_db1.c: revision 1.8
external/bsd/nvi/dist/docs/vi.man/vi.1: revisions 1.3, 1.4
external/bsd/nvi/dist/ex/ex_map.c: revision 1.4
external/bsd/nvi/dist/ex/ex_script.c: revisions 1.5, 1.6
external/bsd/nvi/usr.bin/nvi/Makefile: revision 1.7
PR/50092: Rin Okuyama: Fix memory leaks in vi when resizing.
--
PR/50484: Rin Okuyama: fix the script command of vi(1)
--
Fix > 1024 char lines in script. (Rin Okuyama)
--
remove CONST; it is unused from Brad Harder
--
add default: to appease gcc.
--
Restore the first line of the copyright header, which accidentally got
zapped in -r1.2.
--
PR 51446 Brad Harder: fix synopsis for :tagprev
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.1.6.1 src/external/bsd/nvi/Makefile.inc
cvs rdiff -u -r1.2 -r1.2.6.1 src/external/bsd/nvi/dist/cl/cl.h
cvs rdiff -u -r1.4 -r1.4.6.1 src/external/bsd/nvi/dist/cl/cl_main.c \
src/external/bsd/nvi/dist/cl/cl_screen.c \
src/external/bsd/nvi/dist/cl/cl_term.c
cvs rdiff -u -r1.2 -r1.2.6.1 src/external/bsd/nvi/dist/common/key.h
cvs rdiff -u -r1.7 -r1.7.6.1 src/external/bsd/nvi/dist/common/vi_db1.c
cvs rdiff -u -r1.2 -r1.2.6.1 src/external/bsd/nvi/dist/docs/vi.man/vi.1
cvs rdiff -u -r1.3 -r1.3.6.1 src/external/bsd/nvi/dist/ex/ex_map.c
cvs rdiff -u -r1.4 -r1.4.6.1 src/external/bsd/nvi/dist/ex/ex_script.c
cvs rdiff -u -r1.5 -r1.5.2.1 src/external/bsd/nvi/usr.bin/nvi/Makefile
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.