diff options
author | Joris Vink <joris@cvs.openbsd.org> | 2005-08-09 10:33:47 +0000 |
---|---|---|
committer | Joris Vink <joris@cvs.openbsd.org> | 2005-08-09 10:33:47 +0000 |
commit | 011e7972b55a00035ef01cb1b007db6fd674a3c2 (patch) | |
tree | f4955d1043983db3a67f9a91b66a2f8cff252188 | |
parent | dac8a278f86c1eb83a0f62c12b6d19bad8bbf078 (diff) |
fix our root caching method, it was utterly broken and would
cause opencvs to segfault in several cases.
ok jfb@, xsa@
-rw-r--r-- | usr.bin/cvs/cvs.h | 4 | ||||
-rw-r--r-- | usr.bin/cvs/root.c | 32 |
2 files changed, 17 insertions, 19 deletions
diff --git a/usr.bin/cvs/cvs.h b/usr.bin/cvs/cvs.h index db3eadc6694..6417d02d4f2 100644 --- a/usr.bin/cvs/cvs.h +++ b/usr.bin/cvs/cvs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cvs.h,v 1.77 2005/08/04 13:31:14 xsa Exp $ */ +/* $OpenBSD: cvs.h,v 1.78 2005/08/09 10:33:46 joris Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -213,6 +213,8 @@ struct cvsroot { FILE *cr_srverr; char *cr_version; /* version of remote server */ u_char cr_vrmask[16]; /* mask of valid requests supported by server */ + + TAILQ_ENTRY(cvsroot) root_cache; }; #define CVS_SETVR(rt, rq) ((rt)->cr_vrmask[(rq) / 8] |= (1 << ((rq) % 8))) diff --git a/usr.bin/cvs/root.c b/usr.bin/cvs/root.c index 9ebda0a9603..f470b4e307a 100644 --- a/usr.bin/cvs/root.c +++ b/usr.bin/cvs/root.c @@ -1,4 +1,4 @@ -/* $OpenBSD: root.c,v 1.21 2005/07/25 12:13:08 xsa Exp $ */ +/* $OpenBSD: root.c,v 1.22 2005/08/09 10:33:46 joris Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -65,11 +65,7 @@ const char *cvs_methods[] = { * increases the reference count). Otherwise, it does the parsing and adds * the result to the cache for future hits. */ - -static struct cvsroot **cvs_rcache = NULL; -static u_int cvs_rcsz = 0; - - +static TAILQ_HEAD(, cvsroot) cvs_rcache = TAILQ_HEAD_INITIALIZER(cvs_rcache); /* * cvsroot_parse() @@ -86,13 +82,18 @@ cvsroot_parse(const char *str) { u_int i; char *cp, *sp, *pp; - void *tmp; struct cvsroot *root; - for (i = 0; i < cvs_rcsz; i++) { - if (strcmp(str, cvs_rcache[i]->cr_str) == 0) { - cvs_rcache[i]->cr_ref++; - return (cvs_rcache[i]); + /* + * Look if we have it in cache, if we found it add it to the cache + * at the first position again. + */ + TAILQ_FOREACH(root, &cvs_rcache, root_cache) { + if (strcmp(str, root->cr_str) == 0) { + TAILQ_REMOVE(&cvs_rcache, root, root_cache); + TAILQ_INSERT_HEAD(&cvs_rcache, root, root_cache); + root->cr_ref++; + return (root); } } @@ -214,13 +215,7 @@ cvsroot_parse(const char *str) } /* add to the cache */ - tmp = realloc(cvs_rcache, (cvs_rcsz + 1) * sizeof(struct cvsroot *)); - if (tmp != NULL) { - cvs_rcache = (struct cvsroot **)tmp; - cvs_rcache[cvs_rcsz++] = root; - root->cr_ref++; - } - + TAILQ_INSERT_HEAD(&cvs_rcache, root, root_cache); return (root); } @@ -236,6 +231,7 @@ cvsroot_free(struct cvsroot *root) { root->cr_ref--; if (root->cr_ref == 0) { + TAILQ_REMOVE(&cvs_rcache, root, root_cache); if (root->cr_str != NULL) free(root->cr_str); if (root->cr_buf != NULL) |