Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/bsd/nvi PR/50092: Rin Okuyama: Fix memory leaks in ...
details: https://anonhg.NetBSD.org/src/rev/b6587202e31e
branches: trunk
changeset: 341848:b6587202e31e
user: christos <christos%NetBSD.org@localhost>
date: Wed Nov 25 20:25:20 2015 +0000
description:
PR/50092: Rin Okuyama: Fix memory leaks in vi when resizing.
diffstat:
external/bsd/nvi/Makefile.inc | 4 +-
external/bsd/nvi/dist/cl/cl.h | 6 ++-
external/bsd/nvi/dist/cl/cl_main.c | 21 ++++++++-
external/bsd/nvi/dist/cl/cl_screen.c | 79 ++++++++++++++++++++++++++++-------
external/bsd/nvi/dist/cl/cl_term.c | 10 ++-
5 files changed, 95 insertions(+), 25 deletions(-)
diffs (truncated from 315 to 300 lines):
diff -r f66f4a22af01 -r b6587202e31e external/bsd/nvi/Makefile.inc
--- a/external/bsd/nvi/Makefile.inc Wed Nov 25 19:13:49 2015 +0000
+++ b/external/bsd/nvi/Makefile.inc Wed Nov 25 20:25:20 2015 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.inc,v 1.1 2013/11/22 16:00:45 christos Exp $
+# $NetBSD: Makefile.inc,v 1.2 2015/11/25 20:25:20 christos Exp $
.include <bsd.own.mk>
@@ -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
diff -r f66f4a22af01 -r b6587202e31e external/bsd/nvi/dist/cl/cl.h
--- a/external/bsd/nvi/dist/cl/cl.h Wed Nov 25 19:13:49 2015 +0000
+++ b/external/bsd/nvi/dist/cl/cl.h Wed Nov 25 20:25:20 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cl.h,v 1.2 2013/11/22 15:52:05 christos Exp $ */
+/* $NetBSD: cl.h,v 1.3 2015/11/25 20:25:20 christos Exp $ */
/*-
* Copyright (c) 1993, 1994
* The Regents of the University of California. All rights reserved.
@@ -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;
diff -r f66f4a22af01 -r b6587202e31e external/bsd/nvi/dist/cl/cl_main.c
--- a/external/bsd/nvi/dist/cl/cl_main.c Wed Nov 25 19:13:49 2015 +0000
+++ b/external/bsd/nvi/dist/cl/cl_main.c Wed Nov 25 20:25:20 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cl_main.c,v 1.4 2014/01/26 21:43:45 christos Exp $ */
+/* $NetBSD: cl_main.c,v 1.5 2015/11/25 20:25:20 christos Exp $ */
/*-
* Copyright (c) 1993, 1994
* The Regents of the University of California. All rights reserved.
@@ -16,7 +16,7 @@
static const char sccsid[] = "Id: cl_main.c,v 10.54 2001/07/29 19:07:27 skimo Exp (Berkeley) Date: 2001/07/29 19:07:27 ";
#endif /* not lint */
#else
-__RCSID("$NetBSD: cl_main.c,v 1.4 2014/01/26 21:43:45 christos Exp $");
+__RCSID("$NetBSD: cl_main.c,v 1.5 2015/11/25 20:25:20 christos Exp $");
#endif
#include <sys/types.h>
@@ -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);
}
diff -r f66f4a22af01 -r b6587202e31e external/bsd/nvi/dist/cl/cl_screen.c
--- a/external/bsd/nvi/dist/cl/cl_screen.c Wed Nov 25 19:13:49 2015 +0000
+++ b/external/bsd/nvi/dist/cl/cl_screen.c Wed Nov 25 20:25:20 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cl_screen.c,v 1.4 2014/01/26 21:43:45 christos Exp $ */
+/* $NetBSD: cl_screen.c,v 1.5 2015/11/25 20:25:20 christos Exp $ */
/*-
* Copyright (c) 1993, 1994
* The Regents of the University of California. All rights reserved.
@@ -16,7 +16,7 @@
static const char sccsid[] = "Id: cl_screen.c,v 10.56 2002/05/03 19:59:44 skimo Exp (Berkeley) Date: 2002/05/03 19:59:44 ";
#endif /* not lint */
#else
-__RCSID("$NetBSD: cl_screen.c,v 1.4 2014/01/26 21:43:45 christos Exp $");
+__RCSID("$NetBSD: cl_screen.c,v 1.5 2015/11/25 20:25:20 christos Exp $");
#endif
#include <sys/types.h>
@@ -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,38 @@
CL_PRIVATE *clp;
WINDOW *win;
GS *gp;
+ int ret, error;
+ sigset_t oset;
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.
+ */
+ error = sigprocmask(SIG_BLOCK, &__sigblockset, &oset);
+
/* 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 +125,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 +139,18 @@
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. */
+ if (error == 0)
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ return ret;
}
/*
@@ -234,10 +258,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 +277,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 +402,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 +442,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 +463,8 @@
cl_ex_init(SCR *sp)
{
CL_PRIVATE *clp;
+ int error;
+ const char *ttype;
clp = CLP(sp);
@@ -445,6 +476,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);
diff -r f66f4a22af01 -r b6587202e31e external/bsd/nvi/dist/cl/cl_term.c
--- a/external/bsd/nvi/dist/cl/cl_term.c Wed Nov 25 19:13:49 2015 +0000
+++ b/external/bsd/nvi/dist/cl/cl_term.c Wed Nov 25 20:25:20 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cl_term.c,v 1.4 2014/01/26 21:43:45 christos Exp $ */
+/* $NetBSD: cl_term.c,v 1.5 2015/11/25 20:25:20 christos Exp $ */
/*-
* Copyright (c) 1993, 1994
* The Regents of the University of California. All rights reserved.
@@ -16,7 +16,7 @@
static const char sccsid[] = "Id: cl_term.c,v 10.31 2001/07/08 13:06:56 skimo Exp (Berkeley) Date: 2001/07/08 13:06:56 ";
#endif /* not lint */
#else
-__RCSID("$NetBSD: cl_term.c,v 1.4 2014/01/26 21:43:45 christos Exp $");
+__RCSID("$NetBSD: cl_term.c,v 1.5 2015/11/25 20:25:20 christos Exp $");
#endif
#include <sys/types.h>
@@ -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);
Home |
Main Index |
Thread Index |
Old Index