diff --git a/lib/libterm/termcap.3 b/lib/libterm/termcap.3 index 9a16558bb413..b837a83c2eaa 100644 --- a/lib/libterm/termcap.3 +++ b/lib/libterm/termcap.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: termcap.3,v 1.21 2001/01/05 23:05:08 christos Exp $ +.\" $NetBSD: termcap.3,v 1.22 2001/11/02 18:24:20 christos Exp $ .\" .\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -74,7 +74,7 @@ .Ft char * .Fn t_getstr "struct tinfo *info" "char *id" "char **area" "size_t *limit" .Ft char * -.Fn t_agetstr "struct tinfo *info" "char *id" "char **buffer" "char **area" +.Fn t_agetstr "struct tinfo *info" "char *id" .Ft int .Fn t_getterm "struct tinfo *info" "char **area" "size_t *limit" .Ft int @@ -342,55 +342,11 @@ The function .Fn t_agetstr performs the same function as .Fn t_getstr -except sufficient memory is first allocated to hold the desired string -argument before adding it to the buffer. To initialise the buffer for +except it handles memory allocation automatically. The memory that .Fn t_agetstr -the first call must be done with the contents of -.Fa buffer -set to NULL. Subsequent calls to -.Fn t_agetstr -can pass -.Fa buffer -and -.Fa area -in unmodified and the requested string argument will be appended to -the buffer after sufficient memory has been allocated. Modifying either -.Fa buffer -or -.Fa area -between calls to -.Fn t_agetstr -will certainly lead to the function misbehaving. When the storage -allocated by -.Fn t_agetstr -is no longer required it can be freed by passing the pointer contained -in -.Fa buffer -to -.Fn free . -If an error occurs within -.Fn t_agetstr -a NULL will be returned and -.Fa buffer -and -.Fa area -will remain unmodified. -.Em NOTE -.Fn t_agetstr -uses -.Fn realloc -to reallocate the buffer memory so saving a copy of either -.Fa buffer -or -.Fa area -for use after subsequent calls to -.Fn t_agetstr -is likely to fail. It is best to keep offsets from -.Fa buffer -to the desired string and calculate pointer addresses only after all -the calls to -.Fn t_agetstr -have been done. +allocates will be freed when +.Fn t_freent +is called. .Pp The function .Fn t_getterm diff --git a/lib/libterm/termcap.c b/lib/libterm/termcap.c index 116df9ee316c..78f4b294dab6 100644 --- a/lib/libterm/termcap.c +++ b/lib/libterm/termcap.c @@ -1,4 +1,4 @@ -/* $NetBSD: termcap.c,v 1.39 2001/10/31 21:52:17 christos Exp $ */ +/* $NetBSD: termcap.c,v 1.40 2001/11/02 18:24:20 christos Exp $ */ /* * Copyright (c) 1980, 1993 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)termcap.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: termcap.c,v 1.39 2001/10/31 21:52:17 christos Exp $"); +__RCSID("$NetBSD: termcap.c,v 1.40 2001/11/02 18:24:20 christos Exp $"); #endif #endif /* not lint */ @@ -108,6 +108,7 @@ t_setinfo(struct tinfo **bp, const char *entry) (*bp)->bc = t_getstr(*bp, "bc", &cap_ptr, &limit); if ((*bp)->bc) (*bp)->bc = strdup((*bp)->bc); + (*bp)->tbuf = NULL; return 0; } @@ -251,6 +252,7 @@ t_getent(bp, name) (*bp)->bc = t_getstr(*bp, "bc", &cap_ptr, &limit); if ((*bp)->bc) (*bp)->bc = strdup((*bp)->bc); + (*bp)->tbuf = NULL; } return (i + 1); @@ -460,39 +462,44 @@ tgetstr(id, area) * fix it for now is to allocate a lot -- 8K, and leak if we need to * realloc. This API needs to be destroyed!. */ -#define BSIZE 8192 +#define BSIZE 256 char * -t_agetstr(struct tinfo *info, const char *id, char **bufptr, char **area) +t_agetstr(struct tinfo *info, const char *id) { size_t new_size; - char *new_buf; + struct tbuf *tb; _DIAGASSERT(info != NULL); _DIAGASSERT(id != NULL); - _DIAGASSERT(bufptr != NULL); - _DIAGASSERT(area != NULL); t_getstr(info, id, NULL, &new_size); - /* either the string is empty or the capability does not exist. */ - if (new_size == 0 || new_size > BSIZE) + /* either the string is empty or the capability does not exist. */ + if (new_size == 0) return NULL; - /* check if we have a buffer, if not malloc one and fill it in. */ - if (*bufptr == NULL) { - if ((new_buf = (char *) malloc(BSIZE)) == NULL) + if ((tb = info->tbuf) == NULL || (tb->eptr - tb->ptr) < new_size) { + if (new_size < BSIZE) + new_size = BSIZE; + else + new_size++; + + if ((tb = malloc(sizeof(*info->tbuf))) == NULL) return NULL; - *bufptr = new_buf; - *area = new_buf; - } else if (*area - *bufptr >= BSIZE - new_size) { - char buf[BSIZE]; - char *b = buf; - size_t len = BSIZE; - /* Leak! */ - return strdup(t_getstr(info, id, &b, &len)); + + if ((tb->data = tb->ptr = tb->eptr = malloc(new_size)) == NULL) + return NULL; + + tb->eptr += new_size; + + if (info->tbuf != NULL) + tb->next = info->tbuf; + else + tb->next = NULL; + + info->tbuf = tb; } - return t_getstr(info, id, area, NULL); - + return t_getstr(info, id, &tb->ptr, NULL); } /* @@ -503,12 +510,18 @@ void t_freent(info) struct tinfo *info; { + struct tbuf *tb; _DIAGASSERT(info != NULL); free(info->info); if (info->up != NULL) free(info->up); if (info->bc != NULL) free(info->bc); + for (tb = info->tbuf; tb;) { + tb = info->tbuf->next; + free(info->tbuf->data); + free(info->tbuf); + } free(info); } diff --git a/lib/libterm/termcap.h b/lib/libterm/termcap.h index 6e7f3dc8c9d1..c87c61f23d5f 100644 --- a/lib/libterm/termcap.h +++ b/lib/libterm/termcap.h @@ -1,4 +1,4 @@ -/* $NetBSD: termcap.h,v 1.12 2000/05/28 09:58:15 blymn Exp $ */ +/* $NetBSD: termcap.h,v 1.13 2001/11/02 18:24:20 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -60,7 +60,7 @@ int t_getent __P((struct tinfo **, const char *)); int t_getnum __P((struct tinfo *, const char *)); int t_getflag __P((struct tinfo *, const char *)); char *t_getstr __P((struct tinfo *, const char *, char **, size_t *)); -char *t_agetstr(struct tinfo *, const char *, char **, char **); +char *t_agetstr(struct tinfo *, const char *); int t_getterm(struct tinfo *, char **, size_t *); int t_goto __P((struct tinfo *, const char *, int, int, char *, size_t)); int t_puts __P((struct tinfo *, const char *, int, diff --git a/lib/libterm/termcap_private.h b/lib/libterm/termcap_private.h index c39da2f9675b..85ee84f1756b 100644 --- a/lib/libterm/termcap_private.h +++ b/lib/libterm/termcap_private.h @@ -1,4 +1,4 @@ -/* $NetBSD: termcap_private.h,v 1.3 2001/06/13 10:46:00 wiz Exp $ */ +/* $NetBSD: termcap_private.h,v 1.4 2001/11/02 18:24:20 christos Exp $ */ /*- * Copyright (c) 1998-1999 Brett Lymn @@ -35,9 +35,12 @@ struct tinfo { char *info; - char *up; /* for use by tgoto */ - char *bc; /* for use by tgoto */ + char *up; /* for use by tgoto */ + char *bc; /* for use by tgoto */ + struct tbuf { /* for use by t_agetstr() */ + struct tbuf *next; /* pointer to next area */ + char *data; /* pointer to beginning of buffer */ + char *ptr; /* current data pointer */ + char *eptr; /* pointer to the end of buffer */ + } *tbuf; }; - - -