summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoris Vink <joris@cvs.openbsd.org>2005-08-09 10:33:47 +0000
committerJoris Vink <joris@cvs.openbsd.org>2005-08-09 10:33:47 +0000
commit011e7972b55a00035ef01cb1b007db6fd674a3c2 (patch)
treef4955d1043983db3a67f9a91b66a2f8cff252188
parentdac8a278f86c1eb83a0f62c12b6d19bad8bbf078 (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.h4
-rw-r--r--usr.bin/cvs/root.c32
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)