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/dd8adc4941cc
branches:  trunk
changeset: 811990:dd8adc4941cc
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 d55681af223c -r dd8adc4941cc 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 d55681af223c -r dd8adc4941cc 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 d55681af223c -r dd8adc4941cc 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 d55681af223c -r dd8adc4941cc 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 d55681af223c -r dd8adc4941cc 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