summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2017-08-30 18:13:48 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2017-08-30 18:13:48 +0000
commit42463b28f04e456e36dc0a6ead80facf27df6b0d (patch)
treee32d31c3df7cfb3f43c5027da6771e7c401c16ba /usr.bin
parentffe5ad1155dc407454557005e4d74fc090c28eb6 (diff)
Instead of overloading the line clear function to mean free if
background is default (8), introduce an explicit free function and use it where a free alone is needed. Likewise, use memmove directly rather than grid_move_lines where it makes sense. Based on a memory leak fix by Dan Aloni in GitHub issue 1051.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/tmux/grid-view.c6
-rw-r--r--usr.bin/tmux/grid.c78
-rw-r--r--usr.bin/tmux/tmux.h4
3 files changed, 54 insertions, 34 deletions
diff --git a/usr.bin/tmux/grid-view.c b/usr.bin/tmux/grid-view.c
index 40ade691966..5910aaaf229 100644
--- a/usr.bin/tmux/grid-view.c
+++ b/usr.bin/tmux/grid-view.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: grid-view.c,v 1.29 2017/05/12 13:00:56 nicm Exp $ */
+/* $OpenBSD: grid-view.c,v 1.30 2017/08/30 18:13:47 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -75,7 +75,7 @@ grid_view_clear_history(struct grid *gd, u_int bg)
/* Scroll the lines into the history. */
for (yy = 0; yy < last; yy++) {
- grid_collect_history(gd, bg);
+ grid_collect_history(gd);
grid_scroll_history(gd, bg);
}
if (last < gd->sy)
@@ -100,7 +100,7 @@ grid_view_scroll_region_up(struct grid *gd, u_int rupper, u_int rlower,
u_int bg)
{
if (gd->flags & GRID_HISTORY) {
- grid_collect_history(gd, bg);
+ grid_collect_history(gd);
if (rupper == 0 && rlower == gd->sy - 1)
grid_scroll_history(gd, bg);
else {
diff --git a/usr.bin/tmux/grid.c b/usr.bin/tmux/grid.c
index b570e4e6a79..2b0edb18dad 100644
--- a/usr.bin/tmux/grid.c
+++ b/usr.bin/tmux/grid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: grid.c,v 1.74 2017/05/16 12:57:26 nicm Exp $ */
+/* $OpenBSD: grid.c,v 1.75 2017/08/30 18:13:47 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -162,6 +162,26 @@ grid_cells_equal(const struct grid_cell *gca, const struct grid_cell *gcb)
return (memcmp(gca->data.data, gcb->data.data, gca->data.size) == 0);
}
+/* Free one line. */
+static void
+grid_free_line(struct grid *gd, u_int py)
+{
+ free(gd->linedata[py].celldata);
+ gd->linedata[py].celldata = NULL;
+ free(gd->linedata[py].extddata);
+ gd->linedata[py].extddata = NULL;
+}
+
+/* Free several lines. */
+static void
+grid_free_lines(struct grid *gd, u_int py, u_int ny)
+{
+ u_int yy;
+
+ for (yy = py; yy < py + ny; yy++)
+ grid_free_line(gd, yy);
+}
+
/* Create a new grid. */
struct grid *
grid_create(u_int sx, u_int sy, u_int hlimit)
@@ -187,14 +207,7 @@ grid_create(u_int sx, u_int sy, u_int hlimit)
void
grid_destroy(struct grid *gd)
{
- struct grid_line *gl;
- u_int yy;
-
- for (yy = 0; yy < gd->hsize + gd->sy; yy++) {
- gl = &gd->linedata[yy];
- free(gl->celldata);
- free(gl->extddata);
- }
+ grid_free_lines(gd, 0, gd->hsize + gd->sy);
free(gd->linedata);
@@ -233,19 +246,26 @@ grid_compare(struct grid *ga, struct grid *gb)
* and shift up.
*/
void
-grid_collect_history(struct grid *gd, u_int bg)
+grid_collect_history(struct grid *gd)
{
- u_int yy;
+ u_int ny;
if (gd->hsize < gd->hlimit)
return;
- yy = gd->hlimit / 10;
- if (yy < 1)
- yy = 1;
+ ny = gd->hlimit / 10;
+ if (ny < 1)
+ ny = 1;
- grid_move_lines(gd, 0, yy, gd->hsize + gd->sy - yy, bg);
- gd->hsize -= yy;
+ /*
+ * Free the lines from 0 to ny then move the remaining lines over
+ * them.
+ */
+ grid_free_lines(gd, 0, ny);
+ memmove(&gd->linedata[0], &gd->linedata[ny],
+ (gd->hsize + gd->sy - ny) * (sizeof *gd->linedata));
+
+ gd->hsize -= ny;
if (gd->hscrolled > gd->hsize)
gd->hscrolled = gd->hsize;
}
@@ -272,8 +292,9 @@ grid_scroll_history(struct grid *gd, u_int bg)
void
grid_clear_history(struct grid *gd)
{
- grid_clear_lines(gd, 0, gd->hsize, 8);
- grid_move_lines(gd, 0, gd->hsize, gd->sy, 8);
+ grid_free_lines(gd, 0, gd->hsize);
+ memmove(&gd->linedata[0], &gd->linedata[gd->hsize],
+ gd->sy * (sizeof *gd->linedata));
gd->hscrolled = 0;
gd->hsize = 0;
@@ -481,8 +502,7 @@ grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny, u_int bg)
void
grid_clear_lines(struct grid *gd, u_int py, u_int ny, u_int bg)
{
- struct grid_line *gl;
- u_int yy;
+ u_int yy;
if (ny == 0)
return;
@@ -493,9 +513,7 @@ grid_clear_lines(struct grid *gd, u_int py, u_int ny, u_int bg)
return;
for (yy = py; yy < py + ny; yy++) {
- gl = &gd->linedata[yy];
- free(gl->celldata);
- free(gl->extddata);
+ grid_free_line(gd, yy);
grid_empty_line(gd, yy, bg);
}
}
@@ -522,13 +540,16 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny, u_int bg)
for (yy = dy; yy < dy + ny; yy++) {
if (yy >= py && yy < py + ny)
continue;
- grid_clear_lines(gd, yy, 1, bg);
+ grid_free_line(gd, yy);
}
memmove(&gd->linedata[dy], &gd->linedata[py],
ny * (sizeof *gd->linedata));
- /* Wipe any lines that have been moved (without freeing them). */
+ /*
+ * Wipe any lines that have been moved (without freeing them - they are
+ * still present).
+ */
for (yy = py; yy < py + ny; yy++) {
if (yy < dy || yy >= dy + ny)
grid_empty_line(gd, yy, bg);
@@ -845,9 +866,8 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
}
/*
- * Duplicate a set of lines between two grids. If there aren't enough lines in
- * either source or destination, the number of lines is limited to the number
- * available.
+ * Duplicate a set of lines between two grids. Both source and destination
+ * should be big enough.
*/
void
grid_duplicate_lines(struct grid *dst, u_int dy, struct grid *src, u_int sy,
@@ -860,7 +880,7 @@ grid_duplicate_lines(struct grid *dst, u_int dy, struct grid *src, u_int sy,
ny = dst->hsize + dst->sy - dy;
if (sy + ny > src->hsize + src->sy)
ny = src->hsize + src->sy - sy;
- grid_clear_lines(dst, dy, ny, 8);
+ grid_free_lines(dst, dy, ny);
for (yy = 0; yy < ny; yy++) {
srcl = &src->linedata[sy];
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index e07db1d5b05..f481184ec2c 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.803 2017/08/30 10:33:57 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.804 2017/08/30 18:13:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1973,7 +1973,7 @@ int grid_cells_equal(const struct grid_cell *, const struct grid_cell *);
struct grid *grid_create(u_int, u_int, u_int);
void grid_destroy(struct grid *);
int grid_compare(struct grid *, struct grid *);
-void grid_collect_history(struct grid *, u_int);
+void grid_collect_history(struct grid *);
void grid_scroll_history(struct grid *, u_int);
void grid_scroll_history_region(struct grid *, u_int, u_int, u_int);
void grid_clear_history(struct grid *);