diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2017-08-30 18:13:48 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2017-08-30 18:13:48 +0000 |
commit | 42463b28f04e456e36dc0a6ead80facf27df6b0d (patch) | |
tree | e32d31c3df7cfb3f43c5027da6771e7c401c16ba /usr.bin | |
parent | ffe5ad1155dc407454557005e4d74fc090c28eb6 (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.c | 6 | ||||
-rw-r--r-- | usr.bin/tmux/grid.c | 78 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 4 |
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 *); |