- Fixed memory leak in sc_alloc_history_buffer().
- Correctly observe the variable `extra_history_size' when changing the size of history (scroll back) buffer. - Added sc_free_history_buffer(). Pointed out by: des
This commit is contained in:
parent
e47178acae
commit
c4c9400b69
@ -26,7 +26,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id:$
|
||||
* $Id: schistory.c,v 1.1 1999/06/22 14:13:26 yokota Exp $
|
||||
*/
|
||||
|
||||
#include "sc.h"
|
||||
@ -68,7 +68,7 @@ static void history_to_screen(scr_stat *scp);
|
||||
|
||||
/* allocate a history buffer */
|
||||
int
|
||||
sc_alloc_history_buffer(scr_stat *scp, int lines, int wait)
|
||||
sc_alloc_history_buffer(scr_stat *scp, int lines, int prev_ysize, int wait)
|
||||
{
|
||||
/*
|
||||
* syscons unconditionally allocates buffers upto
|
||||
@ -77,38 +77,82 @@ sc_alloc_history_buffer(scr_stat *scp, int lines, int wait)
|
||||
* subject to extra_history_size.
|
||||
*/
|
||||
sc_vtb_t *history;
|
||||
sc_vtb_t *prev_history;
|
||||
int cur_lines; /* current buffer size */
|
||||
int min_lines; /* guaranteed buffer size */
|
||||
int delta; /* lines to put back */
|
||||
|
||||
if (lines <= 0)
|
||||
lines = SC_HISTORY_SIZE; /* use the default value */
|
||||
lines = imax(lines, scp->ysize);
|
||||
min_lines = imax(SC_HISTORY_SIZE, scp->ysize);
|
||||
|
||||
history = scp->history;
|
||||
/* make it at least as large as the screen size */
|
||||
lines = imax(lines, scp->ysize);
|
||||
|
||||
/* remove the history buffer while we update it */
|
||||
history = prev_history = scp->history;
|
||||
scp->history = NULL;
|
||||
if (history == NULL) {
|
||||
cur_lines = 0;
|
||||
} else {
|
||||
|
||||
/* calculate the amount of lines to put back to extra_history_size */
|
||||
delta = 0;
|
||||
if (prev_history) {
|
||||
cur_lines = sc_vtb_rows(history);
|
||||
min_lines = imax(SC_HISTORY_SIZE, prev_ysize);
|
||||
if (cur_lines > min_lines)
|
||||
extra_history_size += cur_lines - min_lines;
|
||||
sc_vtb_destroy(history);
|
||||
delta = cur_lines - min_lines;
|
||||
}
|
||||
|
||||
if (lines > min_lines)
|
||||
extra_history_size -= lines - min_lines;
|
||||
history = (sc_vtb_t *)malloc(sizeof(*history),
|
||||
M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
|
||||
if (history != NULL)
|
||||
/* lines upto min_lines are always allowed. */
|
||||
min_lines = imax(SC_HISTORY_SIZE, scp->ysize);
|
||||
if (lines > min_lines) {
|
||||
if (lines - min_lines > extra_history_size + delta) {
|
||||
/* too many lines are requested */
|
||||
scp->history = prev_history;
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* destroy the previous buffer and allocate a new one */
|
||||
if (prev_history == NULL) {
|
||||
history = (sc_vtb_t *)malloc(sizeof(*history),
|
||||
M_DEVBUF,
|
||||
(wait) ? M_WAITOK : M_NOWAIT);
|
||||
} else {
|
||||
extra_history_size += delta;
|
||||
sc_vtb_destroy(prev_history);
|
||||
}
|
||||
if (history != NULL) {
|
||||
if (lines > min_lines)
|
||||
extra_history_size -= lines - min_lines;
|
||||
sc_vtb_init(history, VTB_RINGBUFFER, scp->xsize, lines,
|
||||
NULL, wait);
|
||||
}
|
||||
|
||||
scp->history_pos = 0;
|
||||
scp->history = history;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sc_free_history_buffer(scr_stat *scp, int prev_ysize)
|
||||
{
|
||||
sc_vtb_t *history;
|
||||
int cur_lines; /* current buffer size */
|
||||
int min_lines; /* guaranteed buffer size */
|
||||
|
||||
history = scp->history;
|
||||
scp->history = NULL;
|
||||
if (history == NULL)
|
||||
return;
|
||||
|
||||
cur_lines = sc_vtb_rows(history);
|
||||
min_lines = imax(SC_HISTORY_SIZE, prev_ysize);
|
||||
extra_history_size += (cur_lines > min_lines) ? cur_lines - min_lines : 0;
|
||||
|
||||
sc_vtb_destroy(history);
|
||||
free(history, M_DEVBUF);
|
||||
}
|
||||
|
||||
/* copy entire screen into the top of the history buffer */
|
||||
void
|
||||
sc_hist_save(scr_stat *scp)
|
||||
@ -200,6 +244,7 @@ sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
|
||||
struct proc *p)
|
||||
{
|
||||
scr_stat *scp;
|
||||
int error;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
@ -209,9 +254,14 @@ sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
|
||||
return EINVAL;
|
||||
if (scp->status & BUFFER_SAVED)
|
||||
return EBUSY;
|
||||
return sc_alloc_history_buffer(scp,
|
||||
DPRINTF(5, ("lines:%d, ysize:%d, pool:%d\n",
|
||||
*(int *)data, scp->ysize, extra_history_size));
|
||||
error = sc_alloc_history_buffer(scp,
|
||||
imax(*(int *)data, scp->ysize),
|
||||
TRUE);
|
||||
scp->ysize, TRUE);
|
||||
DPRINTF(5, ("error:%d, rows:%d, pool:%d\n", error,
|
||||
sc_vtb_rows(scp->history), extra_history_size));
|
||||
return error;
|
||||
}
|
||||
|
||||
return ENOIOCTL;
|
||||
|
@ -23,7 +23,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: $
|
||||
* $Id: scvidctl.c,v 1.9 1999/06/22 14:13:29 yokota Exp $
|
||||
*/
|
||||
|
||||
#include "sc.h"
|
||||
@ -132,6 +132,7 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
|
||||
video_info_t info;
|
||||
sc_rndr_sw_t *rndr;
|
||||
u_char *font;
|
||||
int prev_ysize;
|
||||
int error;
|
||||
int s;
|
||||
|
||||
@ -188,6 +189,7 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
|
||||
}
|
||||
|
||||
/* set up scp */
|
||||
prev_ysize = scp->ysize;
|
||||
/*
|
||||
* This is a kludge to fend off scrn_update() while we
|
||||
* muck around with scp. XXX
|
||||
@ -210,7 +212,7 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
|
||||
sc_alloc_cut_buffer(scp, FALSE);
|
||||
#endif
|
||||
#ifndef SC_NO_HISTORY
|
||||
sc_alloc_history_buffer(scp, 0, FALSE);
|
||||
sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE);
|
||||
#endif
|
||||
scp->rndr = rndr;
|
||||
splx(s);
|
||||
@ -221,6 +223,8 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
|
||||
|
||||
if (tp == NULL)
|
||||
return 0;
|
||||
DPRINTF(5, ("ws_*size (%d,%d), size (%d,%d)\n",
|
||||
tp->t_winsize.ws_col, tp->t_winsize.ws_row, scp->xsize, scp->ysize));
|
||||
if (tp->t_winsize.ws_col != scp->xsize
|
||||
|| tp->t_winsize.ws_row != scp->ysize) {
|
||||
tp->t_winsize.ws_col = scp->xsize;
|
||||
@ -239,6 +243,7 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
|
||||
#else
|
||||
video_info_t info;
|
||||
sc_rndr_sw_t *rndr;
|
||||
int prev_ysize;
|
||||
int error;
|
||||
int s;
|
||||
|
||||
@ -259,6 +264,7 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
|
||||
}
|
||||
|
||||
/* set up scp */
|
||||
prev_ysize = scp->ysize;
|
||||
scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE);
|
||||
scp->status &= ~PIXEL_MODE;
|
||||
scp->mode = mode;
|
||||
@ -273,6 +279,9 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
|
||||
#ifndef SC_NO_SYSMOUSE
|
||||
/* move the mouse cursor at the center of the screen */
|
||||
sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2);
|
||||
#endif
|
||||
#ifndef SC_NO_HISTORY
|
||||
sc_free_history_buffer(scp, prev_ysize);
|
||||
#endif
|
||||
scp->rndr = rndr;
|
||||
splx(s);
|
||||
@ -305,6 +314,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
|
||||
video_info_t info;
|
||||
sc_rndr_sw_t *rndr;
|
||||
u_char *font;
|
||||
int prev_ysize;
|
||||
int error;
|
||||
int s;
|
||||
|
||||
@ -394,6 +404,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
|
||||
}
|
||||
|
||||
/* set up scp */
|
||||
prev_ysize = scp->ysize;
|
||||
scp->status |= (UNKNOWN_MODE | PIXEL_MODE);
|
||||
scp->status &= ~GRAPHICS_MODE;
|
||||
scp->xsize = xsize;
|
||||
@ -409,7 +420,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
|
||||
sc_alloc_cut_buffer(scp, FALSE);
|
||||
#endif
|
||||
#ifndef SC_NO_HISTORY
|
||||
sc_alloc_history_buffer(scp, 0, FALSE);
|
||||
sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE);
|
||||
#endif
|
||||
scp->rndr = rndr;
|
||||
splx(s);
|
||||
|
@ -25,7 +25,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: syscons.c,v 1.311 1999/07/01 20:29:25 peter Exp $
|
||||
* $Id: syscons.c,v 1.312 1999/07/01 20:43:03 peter Exp $
|
||||
*/
|
||||
|
||||
#include "sc.h"
|
||||
@ -420,7 +420,7 @@ scmeminit(void *arg)
|
||||
|
||||
#ifndef SC_NO_HISTORY
|
||||
/* initialize history buffer & pointers */
|
||||
sc_alloc_history_buffer(sc_console, 0, FALSE);
|
||||
sc_alloc_history_buffer(sc_console, 0, 0, FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -582,11 +582,7 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
|
||||
else {
|
||||
sc_vtb_destroy(&scp->vtb);
|
||||
sc_vtb_destroy(&scp->scr);
|
||||
if (scp->history != NULL) {
|
||||
/* XXX not quite correct */
|
||||
sc_vtb_destroy(scp->history);
|
||||
free(scp->history, M_DEVBUF);
|
||||
}
|
||||
sc_free_history_buffer(scp, scp->ysize);
|
||||
free(scp, M_DEVBUF);
|
||||
sc->console[SC_VTY(dev) - sc->first_vty] = NULL;
|
||||
}
|
||||
@ -3495,7 +3491,7 @@ static scr_stat
|
||||
#endif
|
||||
|
||||
#ifndef SC_NO_HISTORY
|
||||
sc_alloc_history_buffer(scp, 0, TRUE);
|
||||
sc_alloc_history_buffer(scp, 0, 0, TRUE);
|
||||
#endif
|
||||
|
||||
sc_clear_screen(scp);
|
||||
|
@ -25,7 +25,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: syscons.h,v 1.48 1999/06/22 14:13:32 yokota Exp $
|
||||
* $Id: syscons.h,v 1.49 1999/06/24 13:04:33 yokota Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DEV_SYSCONS_SYSCONS_H_
|
||||
@ -430,7 +430,9 @@ void sc_paste(scr_stat *scp, u_char *p, int count);
|
||||
|
||||
/* schistory.c */
|
||||
#ifndef SC_NO_HISTORY
|
||||
int sc_alloc_history_buffer(scr_stat *scp, int lines, int wait);
|
||||
int sc_alloc_history_buffer(scr_stat *scp, int lines,
|
||||
int prev_ysize, int wait);
|
||||
void sc_free_history_buffer(scr_stat *scp, int prev_ysize);
|
||||
void sc_hist_save(scr_stat *scp);
|
||||
#define sc_hist_save_one_line(scp, from) \
|
||||
sc_vtb_append(&(scp)->vtb, (from), (scp)->history, (scp)->xsize)
|
||||
|
Loading…
x
Reference in New Issue
Block a user