diff options
author | yokota <yokota@FreeBSD.org> | 1997-10-23 03:23:50 +0000 |
---|---|---|
committer | yokota <yokota@FreeBSD.org> | 1997-10-23 03:23:50 +0000 |
commit | b13f7d1937225188f0f24693eb4bbc08de1788c7 (patch) | |
tree | 001f102ce8e842198f62cef3d627e7230f5fc2f8 | |
parent | 11e6b28c316cc704cbd4a44e14f3a18fb508d03c (diff) | |
download | FreeBSD-src-b13f7d1937225188f0f24693eb4bbc08de1788c7.zip FreeBSD-src-b13f7d1937225188f0f24693eb4bbc08de1788c7.tar.gz |
Reject unreasonable values passed to CONS_HISTORY ioctl. It did not
check the value and caused kernel panic when a large value was given.
- Move the configuration option SC_HISTORY_SIZE from syscons.h to
syscons.c.
- Define the maximum total number of history lines of all consoles.
It is SC_HISTORY_SIZE*MAXCONS or 1000*MAXCONS; whichever is larger.
CONS_HISTORY will allow the user to set the history size up to
SC_HISTORY_SIZE unconditionally (or the current height of the console
if it is larger than SC_HISTORY_SIZE). If the user requests a larger
buffer, it will be granted only if the total number of all allocated
history lines and the requested number of lines won't exceed the maximum.
- Don't free the previous history buffer and leave the history buffer
pointer holding a invalid pointer. Set the pointer to NULL first, then
free the buffer.
PR: bin/4592
-rw-r--r-- | sys/dev/syscons/syscons.c | 104 | ||||
-rw-r--r-- | sys/dev/syscons/syscons.h | 6 | ||||
-rw-r--r-- | sys/i386/isa/syscons.c | 104 | ||||
-rw-r--r-- | sys/i386/isa/syscons.h | 6 | ||||
-rw-r--r-- | sys/isa/syscons.c | 104 | ||||
-rw-r--r-- | sys/isa/syscons.h | 6 |
6 files changed, 252 insertions, 78 deletions
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index c92bb36..273bb01 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -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.233 1997/09/26 15:27:55 itojun Exp $ + * $Id: syscons.c,v 1.234 1997/10/01 20:46:27 sos Exp $ */ #include "sc.h" @@ -71,6 +71,19 @@ #define MAXCONS 16 #endif +#if !defined(SC_MAX_HISTORY_SIZE) +#define SC_MAX_HISTORY_SIZE (1000 * MAXCONS) +#endif + +#if !defined(SC_HISTORY_SIZE) +#define SC_HISTORY_SIZE (ROW * 4) +#endif + +#if (SC_HISTORY_SIZE * MAXCONS) > SC_MAX_HISTORY_SIZE +#undef SC_MAX_HISTORY_SIZE +#define SC_MAX_HISTORY_SIZE (SC_HISTORY_SIZE * MAXCONS) +#endif + #define COLD 0 #define WARM 1 @@ -147,6 +160,9 @@ static u_short mouse_or_mask[16] = { 0x0000, 0x0000, 0x0000, 0x0000 }; +static int extra_history_size = + SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE * MAXCONS; + static void none_saver(int blank) { } static void (*current_saver)(int blank) = none_saver; int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, @@ -636,10 +652,12 @@ scattach(struct isa_device *dev) scp->mouse_xpos/8); /* initialize history buffer & pointers */ - scp->history_head = scp->history_pos = scp->history = + scp->history_head = scp->history_pos = (u_short *)malloc(scp->history_size*sizeof(u_short), M_DEVBUF, M_NOWAIT); - bzero(scp->history_head, scp->history_size*sizeof(u_short)); + if (scp->history_head != NULL) + bzero(scp->history_head, scp->history_size*sizeof(u_short)); + scp->history = scp->history_head; /* initialize cursor stuff */ if (!(scp->status & UNKNOWN_MODE)) @@ -780,8 +798,13 @@ scclose(dev_t dev, int flag, int mode, struct proc *p) } else { free(scp->scr_buf, M_DEVBUF); - if (scp->history != NULL) + if (scp->history != NULL) { free(scp->history, M_DEVBUF); + if (scp->history_size / scp->xsize + > imax(SC_HISTORY_SIZE, scp->ysize)) + extra_history_size += scp->history_size / scp->xsize + - imax(SC_HISTORY_SIZE, scp->ysize); + } free(scp, M_DEVBUF); console[minor(dev)] = NULL; } @@ -884,6 +907,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) u_int i; struct tty *tp; scr_stat *scp; + u_short *usp; tp = scdevtotty(dev); if (!tp) @@ -956,16 +980,44 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return 0; case CONS_HISTORY: /* set history size */ - if (*data) { + if (*(int *)data > 0) { + int lines; /* buffer size to allocate */ + int lines0; /* current buffer size */ + + lines = imax(*(int *)data, scp->ysize); + lines0 = (scp->history != NULL) ? + scp->history_size / scp->xsize : scp->ysize; + /* + * syscons unconditionally allocates buffers upto SC_HISTORY_SIZE + * lines or scp->ysize lines, whichever is larger. A value + * greater than that is allowed, subject to extra_history_size. + */ + if (lines > imax(lines0, SC_HISTORY_SIZE) + extra_history_size) + return EINVAL; if (cur_console->status & BUFFER_SAVED) return EBUSY; - if (scp->history != NULL) - free(scp->history, M_DEVBUF); - scp->history_size = max(scp->ysize, *(int *)data)*scp->xsize; - scp->history_head = scp->history_pos = scp->history = - (u_short *)malloc(scp->history_size*sizeof(u_short), - M_DEVBUF, M_WAITOK); - bzero(scp->history_head, scp->history_size*sizeof(u_short)); + usp = scp->history; + scp->history = NULL; + if (usp != NULL) + free(usp, M_DEVBUF); + scp->history_size = lines * scp->xsize; + /* + * extra_history_size += + * (lines0 > imax(SC_HISTORY_SIZE, scp->ysize)) ? + * lines0 - imax(SC_HISTORY_SIZE, scp->ysize)) : 0; + * extra_history_size -= + * (lines > imax(SC_HISTORY_SIZE, scp->ysize)) ? + * lines - imax(SC_HISTORY_SIZE, scp->ysize)) : 0; + * lines0 >= ysize && lines >= ysize... Hey, the above can be + * reduced to the following... + */ + extra_history_size += + imax(lines0, SC_HISTORY_SIZE) - imax(lines, SC_HISTORY_SIZE); + usp = (u_short *)malloc(scp->history_size * sizeof(u_short), + M_DEVBUF, M_WAITOK); + bzero(usp, scp->history_size * sizeof(u_short)); + scp->history_head = scp->history_pos = usp; + scp->history = usp; return 0; } else @@ -1129,6 +1181,9 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) if (!crtc_vga || video_mode_ptr == NULL) return ENXIO; + if (scp->history != NULL) + i = imax(scp->history_size / scp->xsize + - imax(SC_HISTORY_SIZE, scp->ysize), 0); switch (cmd & 0xff) { case M_VGA_C80x60: case M_VGA_M80x60: if (!(fonts_loaded & FONT_8)) @@ -1178,13 +1233,19 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) free(cut_buffer, M_DEVBUF); cut_buffer = (char *)malloc(scp->xsize*scp->ysize, M_DEVBUF, M_NOWAIT); cut_buffer[0] = 0x00; - if (scp->history != NULL) - free(scp->history, M_DEVBUF); - scp->history_size = max(HISTORY_SIZE, scp->xsize*scp->ysize); - scp->history_head = scp->history_pos = scp->history = (u_short *) - malloc(scp->history_size*sizeof(u_short), M_DEVBUF, M_NOWAIT); - if (scp->history != NULL) - bzero(scp->history, scp->history_size*sizeof(u_short)); + usp = scp->history; + scp->history = NULL; + if (usp != NULL) { + free(usp, M_DEVBUF); + extra_history_size += i; + } + scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize; + usp = (u_short *)malloc(scp->history_size * sizeof(u_short), + M_DEVBUF, M_NOWAIT); + if (usp != NULL) + bzero(usp, scp->history_size * sizeof(u_short)); + scp->history_head = scp->history_pos = usp; + scp->history = usp; if (scp == cur_console) set_mode(scp); scp->status &= ~UNKNOWN_MODE; @@ -2783,10 +2844,11 @@ static scr_stat scp->mouse_pos = scp->mouse_oldpos = scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize + scp->mouse_xpos/8); - scp->history_head = scp->history_pos = scp->history = + scp->history_head = scp->history_pos = (u_short *)malloc(scp->history_size*sizeof(u_short), M_DEVBUF, M_WAITOK); bzero(scp->history_head, scp->history_size*sizeof(u_short)); + scp->history = scp->history_head; /* SOS if (crtc_vga && video_mode_ptr) set_mode(scp); @@ -2840,7 +2902,7 @@ init_scp(scr_stat *scp) scp->proc = NULL; scp->smode.mode = VT_AUTO; scp->history_head = scp->history_pos = scp->history = NULL; - scp->history_size = max(HISTORY_SIZE, scp->xsize*scp->ysize); + scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize; } static u_char diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h index 0c74c32..ccddf83 100644 --- a/sys/dev/syscons/syscons.h +++ b/sys/dev/syscons/syscons.h @@ -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.33 1997/09/04 23:01:06 yokota Exp $ + * $Id: syscons.h,v 1.34 1997/10/01 20:46:29 sos Exp $ */ #ifndef _I386_ISA_SYSCONS_H_ @@ -102,10 +102,6 @@ #define FONT_8 2 #define FONT_14 4 #define FONT_16 8 -#if !defined(SC_HISTORY_SIZE) -#define SC_HISTORY_SIZE (ROW * 4) -#endif /* SC_HISTORY_SIZE */ -#define HISTORY_SIZE (COL * (SC_HISTORY_SIZE)) /* defines related to hardware addresses */ #define MONO_BASE 0x3B4 /* crt controller base mono */ diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c index c92bb36..273bb01 100644 --- a/sys/i386/isa/syscons.c +++ b/sys/i386/isa/syscons.c @@ -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.233 1997/09/26 15:27:55 itojun Exp $ + * $Id: syscons.c,v 1.234 1997/10/01 20:46:27 sos Exp $ */ #include "sc.h" @@ -71,6 +71,19 @@ #define MAXCONS 16 #endif +#if !defined(SC_MAX_HISTORY_SIZE) +#define SC_MAX_HISTORY_SIZE (1000 * MAXCONS) +#endif + +#if !defined(SC_HISTORY_SIZE) +#define SC_HISTORY_SIZE (ROW * 4) +#endif + +#if (SC_HISTORY_SIZE * MAXCONS) > SC_MAX_HISTORY_SIZE +#undef SC_MAX_HISTORY_SIZE +#define SC_MAX_HISTORY_SIZE (SC_HISTORY_SIZE * MAXCONS) +#endif + #define COLD 0 #define WARM 1 @@ -147,6 +160,9 @@ static u_short mouse_or_mask[16] = { 0x0000, 0x0000, 0x0000, 0x0000 }; +static int extra_history_size = + SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE * MAXCONS; + static void none_saver(int blank) { } static void (*current_saver)(int blank) = none_saver; int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, @@ -636,10 +652,12 @@ scattach(struct isa_device *dev) scp->mouse_xpos/8); /* initialize history buffer & pointers */ - scp->history_head = scp->history_pos = scp->history = + scp->history_head = scp->history_pos = (u_short *)malloc(scp->history_size*sizeof(u_short), M_DEVBUF, M_NOWAIT); - bzero(scp->history_head, scp->history_size*sizeof(u_short)); + if (scp->history_head != NULL) + bzero(scp->history_head, scp->history_size*sizeof(u_short)); + scp->history = scp->history_head; /* initialize cursor stuff */ if (!(scp->status & UNKNOWN_MODE)) @@ -780,8 +798,13 @@ scclose(dev_t dev, int flag, int mode, struct proc *p) } else { free(scp->scr_buf, M_DEVBUF); - if (scp->history != NULL) + if (scp->history != NULL) { free(scp->history, M_DEVBUF); + if (scp->history_size / scp->xsize + > imax(SC_HISTORY_SIZE, scp->ysize)) + extra_history_size += scp->history_size / scp->xsize + - imax(SC_HISTORY_SIZE, scp->ysize); + } free(scp, M_DEVBUF); console[minor(dev)] = NULL; } @@ -884,6 +907,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) u_int i; struct tty *tp; scr_stat *scp; + u_short *usp; tp = scdevtotty(dev); if (!tp) @@ -956,16 +980,44 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return 0; case CONS_HISTORY: /* set history size */ - if (*data) { + if (*(int *)data > 0) { + int lines; /* buffer size to allocate */ + int lines0; /* current buffer size */ + + lines = imax(*(int *)data, scp->ysize); + lines0 = (scp->history != NULL) ? + scp->history_size / scp->xsize : scp->ysize; + /* + * syscons unconditionally allocates buffers upto SC_HISTORY_SIZE + * lines or scp->ysize lines, whichever is larger. A value + * greater than that is allowed, subject to extra_history_size. + */ + if (lines > imax(lines0, SC_HISTORY_SIZE) + extra_history_size) + return EINVAL; if (cur_console->status & BUFFER_SAVED) return EBUSY; - if (scp->history != NULL) - free(scp->history, M_DEVBUF); - scp->history_size = max(scp->ysize, *(int *)data)*scp->xsize; - scp->history_head = scp->history_pos = scp->history = - (u_short *)malloc(scp->history_size*sizeof(u_short), - M_DEVBUF, M_WAITOK); - bzero(scp->history_head, scp->history_size*sizeof(u_short)); + usp = scp->history; + scp->history = NULL; + if (usp != NULL) + free(usp, M_DEVBUF); + scp->history_size = lines * scp->xsize; + /* + * extra_history_size += + * (lines0 > imax(SC_HISTORY_SIZE, scp->ysize)) ? + * lines0 - imax(SC_HISTORY_SIZE, scp->ysize)) : 0; + * extra_history_size -= + * (lines > imax(SC_HISTORY_SIZE, scp->ysize)) ? + * lines - imax(SC_HISTORY_SIZE, scp->ysize)) : 0; + * lines0 >= ysize && lines >= ysize... Hey, the above can be + * reduced to the following... + */ + extra_history_size += + imax(lines0, SC_HISTORY_SIZE) - imax(lines, SC_HISTORY_SIZE); + usp = (u_short *)malloc(scp->history_size * sizeof(u_short), + M_DEVBUF, M_WAITOK); + bzero(usp, scp->history_size * sizeof(u_short)); + scp->history_head = scp->history_pos = usp; + scp->history = usp; return 0; } else @@ -1129,6 +1181,9 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) if (!crtc_vga || video_mode_ptr == NULL) return ENXIO; + if (scp->history != NULL) + i = imax(scp->history_size / scp->xsize + - imax(SC_HISTORY_SIZE, scp->ysize), 0); switch (cmd & 0xff) { case M_VGA_C80x60: case M_VGA_M80x60: if (!(fonts_loaded & FONT_8)) @@ -1178,13 +1233,19 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) free(cut_buffer, M_DEVBUF); cut_buffer = (char *)malloc(scp->xsize*scp->ysize, M_DEVBUF, M_NOWAIT); cut_buffer[0] = 0x00; - if (scp->history != NULL) - free(scp->history, M_DEVBUF); - scp->history_size = max(HISTORY_SIZE, scp->xsize*scp->ysize); - scp->history_head = scp->history_pos = scp->history = (u_short *) - malloc(scp->history_size*sizeof(u_short), M_DEVBUF, M_NOWAIT); - if (scp->history != NULL) - bzero(scp->history, scp->history_size*sizeof(u_short)); + usp = scp->history; + scp->history = NULL; + if (usp != NULL) { + free(usp, M_DEVBUF); + extra_history_size += i; + } + scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize; + usp = (u_short *)malloc(scp->history_size * sizeof(u_short), + M_DEVBUF, M_NOWAIT); + if (usp != NULL) + bzero(usp, scp->history_size * sizeof(u_short)); + scp->history_head = scp->history_pos = usp; + scp->history = usp; if (scp == cur_console) set_mode(scp); scp->status &= ~UNKNOWN_MODE; @@ -2783,10 +2844,11 @@ static scr_stat scp->mouse_pos = scp->mouse_oldpos = scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize + scp->mouse_xpos/8); - scp->history_head = scp->history_pos = scp->history = + scp->history_head = scp->history_pos = (u_short *)malloc(scp->history_size*sizeof(u_short), M_DEVBUF, M_WAITOK); bzero(scp->history_head, scp->history_size*sizeof(u_short)); + scp->history = scp->history_head; /* SOS if (crtc_vga && video_mode_ptr) set_mode(scp); @@ -2840,7 +2902,7 @@ init_scp(scr_stat *scp) scp->proc = NULL; scp->smode.mode = VT_AUTO; scp->history_head = scp->history_pos = scp->history = NULL; - scp->history_size = max(HISTORY_SIZE, scp->xsize*scp->ysize); + scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize; } static u_char diff --git a/sys/i386/isa/syscons.h b/sys/i386/isa/syscons.h index 0c74c32..ccddf83 100644 --- a/sys/i386/isa/syscons.h +++ b/sys/i386/isa/syscons.h @@ -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.33 1997/09/04 23:01:06 yokota Exp $ + * $Id: syscons.h,v 1.34 1997/10/01 20:46:29 sos Exp $ */ #ifndef _I386_ISA_SYSCONS_H_ @@ -102,10 +102,6 @@ #define FONT_8 2 #define FONT_14 4 #define FONT_16 8 -#if !defined(SC_HISTORY_SIZE) -#define SC_HISTORY_SIZE (ROW * 4) -#endif /* SC_HISTORY_SIZE */ -#define HISTORY_SIZE (COL * (SC_HISTORY_SIZE)) /* defines related to hardware addresses */ #define MONO_BASE 0x3B4 /* crt controller base mono */ diff --git a/sys/isa/syscons.c b/sys/isa/syscons.c index c92bb36..273bb01 100644 --- a/sys/isa/syscons.c +++ b/sys/isa/syscons.c @@ -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.233 1997/09/26 15:27:55 itojun Exp $ + * $Id: syscons.c,v 1.234 1997/10/01 20:46:27 sos Exp $ */ #include "sc.h" @@ -71,6 +71,19 @@ #define MAXCONS 16 #endif +#if !defined(SC_MAX_HISTORY_SIZE) +#define SC_MAX_HISTORY_SIZE (1000 * MAXCONS) +#endif + +#if !defined(SC_HISTORY_SIZE) +#define SC_HISTORY_SIZE (ROW * 4) +#endif + +#if (SC_HISTORY_SIZE * MAXCONS) > SC_MAX_HISTORY_SIZE +#undef SC_MAX_HISTORY_SIZE +#define SC_MAX_HISTORY_SIZE (SC_HISTORY_SIZE * MAXCONS) +#endif + #define COLD 0 #define WARM 1 @@ -147,6 +160,9 @@ static u_short mouse_or_mask[16] = { 0x0000, 0x0000, 0x0000, 0x0000 }; +static int extra_history_size = + SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE * MAXCONS; + static void none_saver(int blank) { } static void (*current_saver)(int blank) = none_saver; int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, @@ -636,10 +652,12 @@ scattach(struct isa_device *dev) scp->mouse_xpos/8); /* initialize history buffer & pointers */ - scp->history_head = scp->history_pos = scp->history = + scp->history_head = scp->history_pos = (u_short *)malloc(scp->history_size*sizeof(u_short), M_DEVBUF, M_NOWAIT); - bzero(scp->history_head, scp->history_size*sizeof(u_short)); + if (scp->history_head != NULL) + bzero(scp->history_head, scp->history_size*sizeof(u_short)); + scp->history = scp->history_head; /* initialize cursor stuff */ if (!(scp->status & UNKNOWN_MODE)) @@ -780,8 +798,13 @@ scclose(dev_t dev, int flag, int mode, struct proc *p) } else { free(scp->scr_buf, M_DEVBUF); - if (scp->history != NULL) + if (scp->history != NULL) { free(scp->history, M_DEVBUF); + if (scp->history_size / scp->xsize + > imax(SC_HISTORY_SIZE, scp->ysize)) + extra_history_size += scp->history_size / scp->xsize + - imax(SC_HISTORY_SIZE, scp->ysize); + } free(scp, M_DEVBUF); console[minor(dev)] = NULL; } @@ -884,6 +907,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) u_int i; struct tty *tp; scr_stat *scp; + u_short *usp; tp = scdevtotty(dev); if (!tp) @@ -956,16 +980,44 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return 0; case CONS_HISTORY: /* set history size */ - if (*data) { + if (*(int *)data > 0) { + int lines; /* buffer size to allocate */ + int lines0; /* current buffer size */ + + lines = imax(*(int *)data, scp->ysize); + lines0 = (scp->history != NULL) ? + scp->history_size / scp->xsize : scp->ysize; + /* + * syscons unconditionally allocates buffers upto SC_HISTORY_SIZE + * lines or scp->ysize lines, whichever is larger. A value + * greater than that is allowed, subject to extra_history_size. + */ + if (lines > imax(lines0, SC_HISTORY_SIZE) + extra_history_size) + return EINVAL; if (cur_console->status & BUFFER_SAVED) return EBUSY; - if (scp->history != NULL) - free(scp->history, M_DEVBUF); - scp->history_size = max(scp->ysize, *(int *)data)*scp->xsize; - scp->history_head = scp->history_pos = scp->history = - (u_short *)malloc(scp->history_size*sizeof(u_short), - M_DEVBUF, M_WAITOK); - bzero(scp->history_head, scp->history_size*sizeof(u_short)); + usp = scp->history; + scp->history = NULL; + if (usp != NULL) + free(usp, M_DEVBUF); + scp->history_size = lines * scp->xsize; + /* + * extra_history_size += + * (lines0 > imax(SC_HISTORY_SIZE, scp->ysize)) ? + * lines0 - imax(SC_HISTORY_SIZE, scp->ysize)) : 0; + * extra_history_size -= + * (lines > imax(SC_HISTORY_SIZE, scp->ysize)) ? + * lines - imax(SC_HISTORY_SIZE, scp->ysize)) : 0; + * lines0 >= ysize && lines >= ysize... Hey, the above can be + * reduced to the following... + */ + extra_history_size += + imax(lines0, SC_HISTORY_SIZE) - imax(lines, SC_HISTORY_SIZE); + usp = (u_short *)malloc(scp->history_size * sizeof(u_short), + M_DEVBUF, M_WAITOK); + bzero(usp, scp->history_size * sizeof(u_short)); + scp->history_head = scp->history_pos = usp; + scp->history = usp; return 0; } else @@ -1129,6 +1181,9 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) if (!crtc_vga || video_mode_ptr == NULL) return ENXIO; + if (scp->history != NULL) + i = imax(scp->history_size / scp->xsize + - imax(SC_HISTORY_SIZE, scp->ysize), 0); switch (cmd & 0xff) { case M_VGA_C80x60: case M_VGA_M80x60: if (!(fonts_loaded & FONT_8)) @@ -1178,13 +1233,19 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) free(cut_buffer, M_DEVBUF); cut_buffer = (char *)malloc(scp->xsize*scp->ysize, M_DEVBUF, M_NOWAIT); cut_buffer[0] = 0x00; - if (scp->history != NULL) - free(scp->history, M_DEVBUF); - scp->history_size = max(HISTORY_SIZE, scp->xsize*scp->ysize); - scp->history_head = scp->history_pos = scp->history = (u_short *) - malloc(scp->history_size*sizeof(u_short), M_DEVBUF, M_NOWAIT); - if (scp->history != NULL) - bzero(scp->history, scp->history_size*sizeof(u_short)); + usp = scp->history; + scp->history = NULL; + if (usp != NULL) { + free(usp, M_DEVBUF); + extra_history_size += i; + } + scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize; + usp = (u_short *)malloc(scp->history_size * sizeof(u_short), + M_DEVBUF, M_NOWAIT); + if (usp != NULL) + bzero(usp, scp->history_size * sizeof(u_short)); + scp->history_head = scp->history_pos = usp; + scp->history = usp; if (scp == cur_console) set_mode(scp); scp->status &= ~UNKNOWN_MODE; @@ -2783,10 +2844,11 @@ static scr_stat scp->mouse_pos = scp->mouse_oldpos = scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize + scp->mouse_xpos/8); - scp->history_head = scp->history_pos = scp->history = + scp->history_head = scp->history_pos = (u_short *)malloc(scp->history_size*sizeof(u_short), M_DEVBUF, M_WAITOK); bzero(scp->history_head, scp->history_size*sizeof(u_short)); + scp->history = scp->history_head; /* SOS if (crtc_vga && video_mode_ptr) set_mode(scp); @@ -2840,7 +2902,7 @@ init_scp(scr_stat *scp) scp->proc = NULL; scp->smode.mode = VT_AUTO; scp->history_head = scp->history_pos = scp->history = NULL; - scp->history_size = max(HISTORY_SIZE, scp->xsize*scp->ysize); + scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize; } static u_char diff --git a/sys/isa/syscons.h b/sys/isa/syscons.h index 0c74c32..ccddf83 100644 --- a/sys/isa/syscons.h +++ b/sys/isa/syscons.h @@ -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.33 1997/09/04 23:01:06 yokota Exp $ + * $Id: syscons.h,v 1.34 1997/10/01 20:46:29 sos Exp $ */ #ifndef _I386_ISA_SYSCONS_H_ @@ -102,10 +102,6 @@ #define FONT_8 2 #define FONT_14 4 #define FONT_16 8 -#if !defined(SC_HISTORY_SIZE) -#define SC_HISTORY_SIZE (ROW * 4) -#endif /* SC_HISTORY_SIZE */ -#define HISTORY_SIZE (COL * (SC_HISTORY_SIZE)) /* defines related to hardware addresses */ #define MONO_BASE 0x3B4 /* crt controller base mono */ |