summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Nicholson <dbn.lists@gmail.com>2008-09-23 07:51:47 -0700
committerDan Nicholson <dbn.lists@gmail.com>2008-11-02 09:49:00 -0800
commit29ed87c7a77549400da3a59490d5f996ffea5da2 (patch)
treefc120dc6b71f6aafa36670331881fda370fcbeeb
parentba61d1f2393ca12ec664f0836a673c86558936aa (diff)
Use nodes in list instead of duplicating all initd types
Currently, the entire initd structure is duplicated each time a list is copied. Since the initd is not specific to each list, this could cause problems where changing a value in one initd would not be reflected in the equivalent initd in another list. This also wastes memory as each initd duplicated when only one copy is needed. This change introduces the initd_node type. It points to an initd type and contains the list pointers for inclusion in an initd_list type. The typical constructors and destructors have been added for handling these types in lists. Quite a few places needed to be changed where there were iterations over lists. We should really add accessor functions and use those whenever we need access to members of a list.
-rw-r--r--lib/initd-list.c72
-rw-r--r--lib/initd-types.h17
-rw-r--r--lib/initd.c37
-rw-r--r--lib/initd.h6
-rw-r--r--lib/installrm.c13
-rw-r--r--lib/rdep.c18
-rw-r--r--test/tactive.c5
-rw-r--r--test/tadd-deps1.c6
-rw-r--r--test/tadd-deps2.c6
-rw-r--r--test/tinitd-list.c4
-rw-r--r--test/tinstall.c6
-rw-r--r--test/tparse-dir.c4
-rw-r--r--test/trem-deps.c6
-rw-r--r--test/tremove.c6
14 files changed, 145 insertions, 61 deletions
diff --git a/lib/initd-list.c b/lib/initd-list.c
index 79dea34..8e1b585 100644
--- a/lib/initd-list.c
+++ b/lib/initd-list.c
@@ -29,7 +29,7 @@ initd_list_t *initd_list_new(void)
void initd_list_free(initd_list_t *ilp)
{
- initd_t *cur, *nxt;
+ initd_node_t *cur, *nxt;
if (!ilp)
return;
@@ -37,50 +37,67 @@ void initd_list_free(initd_list_t *ilp)
/* free the members of the initd list */
for (cur = ilp->first; cur; cur = nxt) {
nxt = cur->next;
- initd_free(cur);
+ initd_node_free(cur);
}
free(ilp);
ilp = NULL;
}
-void initd_list_add(initd_list_t *ilp, initd_t *ip)
+void initd_list_add_node(initd_list_t *ilp, initd_node_t *inp)
{
- initd_t *cur;
+ initd_node_t *cur;
/* create a new list if necessary */
if (!ilp)
ilp = initd_list_new();
- /* just return if NULL was passed as initd */
- if (!ip)
+ /* just return if a NULL node was passed */
+ if (!inp)
return;
cur = ilp->last;
if (!cur) {
/* this is the first element */
- ilp->first = ip;
+ ilp->first = inp;
} else {
- cur->next = ip;
- ip->prev = cur;
+ cur->next = inp;
+ inp->prev = cur;
}
- ilp->last = ip;
+ ilp->last = inp;
+}
+
+void initd_list_add(initd_list_t *ilp, initd_t *ip)
+{
+ initd_node_t *node;
+
+ /* create a new list if necessary */
+ if (!ilp)
+ ilp = initd_list_new();
+
+ /* just return if NULL was passed as initd */
+ if (!ip)
+ return;
+
+ /* create a new node with this initd and add it to the list*/
+ node = initd_node_new(ip);
+ initd_list_add_node(ilp, node);
}
/* Remove the last element from an initd list */
void initd_list_pop(initd_list_t *ilp)
{
- initd_t *cur;
+ initd_node_t *cur;
if (!ilp || !ilp->last)
return;
if (ilp->first == ilp->last) {
- initd_free(ilp->first);
+ initd_node_free(ilp->first);
ilp->first = ilp->last = NULL;
} else {
cur = ilp->last->prev;
- initd_free(cur->next);
+ initd_node_free(cur->next);
cur->next = NULL;
ilp->last = cur;
}
@@ -141,15 +158,15 @@ out:
initd_list_t *initd_list_copy(const initd_list_t *source)
{
- initd_t *iold, *inew;
+ initd_node_t *iold, *inew;
initd_list_t *dest = initd_list_new();
if (!source)
goto out;
for (iold = source->first; iold; iold = iold->next) {
- inew = initd_copy(iold);
- initd_list_add(dest, inew);
+ inew = initd_node_copy(iold);
+ initd_list_add_node(dest, inew);
}
out:
@@ -158,15 +175,20 @@ out:
initd_t *initd_list_find_name(const initd_list_t *ilp, const char *name)
{
+ initd_node_t *inp;
initd_t *ip = NULL;
if (!(name || ilp))
goto out;
- for (ip = ilp->first; ip; ip = ip->next) {
+ for (inp = ilp->first; inp; inp = inp->next) {
+ ip = inp->initd;
if (strcmp(ip->name, name) == 0)
break;
}
+
+ if (!inp)
+ ip = NULL;
out:
return ip;
}
@@ -175,14 +197,16 @@ out:
* NULL when not found. */
initd_t *initd_list_find_provides(const initd_list_t *ilp, const char *serv)
{
- initd_t *cur;
+ initd_node_t *cur;
+ initd_t *ip;
if (!ilp)
goto err;
for (cur = ilp->first; cur; cur = cur->next) {
- if (initd_provides(cur, serv))
- return cur;
+ ip = cur->initd;
+ if (initd_provides(ip, serv))
+ return ip;
}
err:
@@ -258,16 +282,18 @@ out:
char *initd_list_verify_all(const initd_list_t *ilp)
{
char *missing = NULL;
- initd_t *cur;
+ initd_node_t *cur;
+ initd_t *ip;
if (!ilp)
goto out;
for (cur = ilp->first; cur; cur = cur->next) {
- missing = initd_verify_deps(ilp, cur, KEY_RSTART);
+ ip = cur->initd;
+ missing = initd_verify_deps(ilp, ip, KEY_RSTART);
if (missing)
break;
- missing = initd_verify_deps(ilp, cur, KEY_RSTOP);
+ missing = initd_verify_deps(ilp, ip, KEY_RSTOP);
if (missing)
break;
}
diff --git a/lib/initd-types.h b/lib/initd-types.h
index 7a8c74c..2b604d9 100644
--- a/lib/initd-types.h
+++ b/lib/initd-types.h
@@ -101,15 +101,20 @@ typedef struct initd {
char *sdesc; /* Short-Description */
char *desc; /* Description */
-
- struct initd *prev;
- struct initd *next;
} initd_t;
-/* linked list of initd types */
+/* The initd node type */
+typedef struct initd_node {
+ initd_t *initd;
+
+ struct initd_node *prev;
+ struct initd_node *next;
+} initd_node_t;
+
+/* linked list of initd_node types */
typedef struct initd_list {
- initd_t *first;
- initd_t *last;
+ initd_node_t *first;
+ initd_node_t *last;
} initd_list_t;
#endif /* _initd_types_h_ */
diff --git a/lib/initd.c b/lib/initd.c
index 050dc87..2a2f07e 100644
--- a/lib/initd.c
+++ b/lib/initd.c
@@ -35,9 +35,6 @@ initd_t *initd_new(const char *name) {
ip->sdesc = ip->desc = NULL;
- ip->prev = NULL;
- ip->next = NULL;
-
return ip;
}
@@ -106,6 +103,40 @@ out:
return dest;
}
+initd_node_t *initd_node_new(const initd_t *ip)
+{
+ initd_node_t *inp = malloc(sizeof(initd_node_t));
+ if (!inp)
+ error(2, errno, "%s", __FUNCTION__);
+
+ inp->initd = (initd_t *) ip;
+ inp->prev = NULL;
+ inp->next = NULL;
+
+ return inp;
+}
+
+void initd_node_free(initd_node_t *inp)
+{
+ if (inp->initd)
+ initd_free(inp->initd);
+
+ free(inp);
+ inp = NULL;
+}
+
+initd_node_t *initd_node_copy(const initd_node_t *source)
+{
+ initd_node_t *dest;
+
+ if (source)
+ dest = initd_node_new(source->initd);
+ else
+ dest = initd_node_new(NULL);
+
+ return dest;
+}
+
/* Set the bits of the rc mask in the specified key */
void initd_set_rc(const initd_t *ip, initd_key_t key, initd_rc_t level)
{
diff --git a/lib/initd.h b/lib/initd.h
index 9ecb6ae..cf25ffd 100644
--- a/lib/initd.h
+++ b/lib/initd.h
@@ -21,6 +21,10 @@ extern void initd_free(initd_t *ip);
extern initd_t *initd_copy(const initd_t *source);
extern initd_t *initd_parse(const char *path);
+extern initd_node_t *initd_node_new(const initd_t *ip);
+extern void initd_node_free(initd_node_t *inp);
+extern initd_node_t *initd_node_copy(const initd_node_t *source);
+
/* Setters */
#define initd_add_prov(ip, name) prov_add(ip->prov, name)
#define initd_add_rstart(ip, name) dep_add(ip->rstart, name)
@@ -41,6 +45,8 @@ extern void initd_add_implicit_prov(initd_t *ip);
/* List functions */
extern initd_list_t *initd_list_new(void);
extern void initd_list_free(initd_list_t *ilp);
+extern void initd_list_add_node(initd_list_t *ilp, initd_node_t *inp);
+#define initd_list_push_node initd_list_add_node
extern void initd_list_add(initd_list_t *ilp, initd_t *ip);
#define initd_list_push initd_list_add
extern void initd_list_pop(initd_list_t *ilp);
diff --git a/lib/installrm.c b/lib/installrm.c
index 78fbbd8..f9fafbe 100644
--- a/lib/installrm.c
+++ b/lib/installrm.c
@@ -81,6 +81,7 @@ void initd_installrm_set_verbose(bool verbose)
static void install_level_links(const initd_list_t *ilp,
const struct rcpair *rcp, initd_sk_t sk)
{
+ initd_node_t *inp;
initd_t *ip;
initd_rc_t rc = rcp->rc;
char *dir = rcp->dir;
@@ -116,7 +117,9 @@ static void install_level_links(const initd_list_t *ilp,
/* First remove existing links, beginning with the head of the
* list for start links. */
if (sk == SK_START) {
- for (ip = ilp->first; ip; ip = ip->next) {
+ for (inp = ilp->first; inp; inp = inp->next) {
+ ip = inp->initd;
+
/* skip script if not active in this level */
if (!initd_is_active(ip, rc, KEY_ASTART))
continue;
@@ -124,7 +127,9 @@ static void install_level_links(const initd_list_t *ilp,
remove_existing_link(ip, rcp, sk);
}
} else {
- for (ip = ilp->last; ip; ip = ip->prev) {
+ for (inp = ilp->last; inp; inp = inp->prev) {
+ ip = inp->initd;
+
/* skip script if not active in this level */
if (!initd_is_active(ip, rc, KEY_ASTOP))
continue;
@@ -134,8 +139,8 @@ static void install_level_links(const initd_list_t *ilp,
}
/* Then install new links */
- for (ip = ilp->first; ip; ip = ip->next)
- install_new_link(ip, rcp, sk, &sk_prio);
+ for (inp = ilp->first; inp; inp = inp->next)
+ install_new_link(inp->initd, rcp, sk, &sk_prio);
}
static void remove_existing_link(const initd_t *ip,
diff --git a/lib/rdep.c b/lib/rdep.c
index a143694..90b27f1 100644
--- a/lib/rdep.c
+++ b/lib/rdep.c
@@ -74,6 +74,7 @@ initd_list_t *initd_remove_recurse_deps(initd_list_t *pool,
initd_sk_t sk, const dep_t *remove)
{
initd_list_t *rmlist = NULL, *all = NULL, *chain = NULL;
+ initd_node_t *inp;
initd_t *ip;
int n;
initd_key_t akey, rmkey;
@@ -126,7 +127,7 @@ initd_list_t *initd_remove_recurse_deps(initd_list_t *pool,
initd_set_rc(ip, rmkey, RC_ALL);
/* Add the initd_t to the rmlist */
- initd_list_add(rmlist, initd_copy(ip));
+ initd_list_add(rmlist, ip);
}
/* If none of the specified services are currently active, the
@@ -152,8 +153,9 @@ initd_list_t *initd_remove_recurse_deps(initd_list_t *pool,
/* Append the rmlist to the all list. Since they are marked for
* removal, they won't be reinstalled. */
- for (ip = rmlist->first; ip; ip = ip->next) {
+ for (inp = rmlist->first; inp; inp = inp->next) {
/* Don't duplicate */
+ ip = inp->initd;
if (!initd_list_exists_name(all, ip->name))
initd_list_add(all, ip);
}
@@ -211,6 +213,7 @@ static dep_t *add_all_active(const initd_list_t *pool,
const dep_t *init, initd_sk_t sk)
{
dep_t *active;
+ initd_node_t *inp;
initd_t *ip;
initd_key_t key, rmkey;
@@ -226,9 +229,10 @@ static dep_t *add_all_active(const initd_list_t *pool,
rmkey = KEY_RMSTOP;
}
- for (ip = pool->first; ip; ip = ip->next) {
+ for (inp = pool->first; inp; inp = inp->next) {
/* Add services if they are active on any level and
* they are not marked for removal on any levels */
+ ip = inp->initd;
if (initd_is_active(ip, RC_ALL, key) &&
!initd_is_active(ip, RC_ALL, rmkey))
dep_add(active, ip->name);
@@ -318,7 +322,7 @@ static bool _recurse_deps(initd_list_t *pool, initd_sk_t sk,
}
/* add it to the chain */
- initd_list_add(chain_deps, initd_copy(cip));
+ initd_list_add(chain_deps, cip);
/* process its required dependencies */
level++;
@@ -377,7 +381,7 @@ static bool _recurse_deps(initd_list_t *pool, initd_sk_t sk,
cstr, cip->name);
}
}
- initd_list_add(all_deps, initd_copy(cip));
+ initd_list_add(all_deps, cip);
initd_list_pop(chain_deps);
}
@@ -408,6 +412,7 @@ static bool initd_list_verify_level(const initd_list_t *ord,
initd_rc_t rc, initd_sk_t sk,
bool required)
{
+ initd_node_t *inp;
initd_t *ip, *dep;
dep_t *iprcdep;
char *dstr;
@@ -429,7 +434,8 @@ static bool initd_list_verify_level(const initd_list_t *ord,
}
/* Check the deps are valid in this level */
- for (ip = ord->first; ip; ip = ip->next) {
+ for (inp = ord->first; inp; inp = inp->next) {
+ ip = inp->initd;
if (sk == SK_START) {
if (required)
iprcdep = ip->rstart;
diff --git a/test/tactive.c b/test/tactive.c
index 1439386..2bac212 100644
--- a/test/tactive.c
+++ b/test/tactive.c
@@ -30,13 +30,16 @@ int main(int argc, char *argv[])
static void print_actives(const initd_list_t *ilp)
{
+ initd_node_t *inp;
initd_t *ip;
int n, nstr;
if (!ilp)
return;
- for (ip = ilp->first; ip; ip = ip->next) {
+ for (inp = ilp->first; inp; inp = inp->next) {
+ ip = inp->initd;
+
printf("%s active start levels:", ip->name);
print_rc_string(ip, SK_START);
diff --git a/test/tadd-deps1.c b/test/tadd-deps1.c
index b11c419..4310d0c 100644
--- a/test/tadd-deps1.c
+++ b/test/tadd-deps1.c
@@ -82,7 +82,7 @@ int main(int argc, char *argv[])
static void print_sk_list(const initd_list_t *list, initd_sk_t sk)
{
char *startstop;
- initd_t *ip;
+ initd_node_t *inp;
switch (sk) {
case SK_START:
@@ -98,8 +98,8 @@ static void print_sk_list(const initd_list_t *list, initd_sk_t sk)
if (list && list->first) {
printf("All deps for %s\n", startstop);
printf("Ordered:");
- for (ip = list->first; ip; ip = ip->next)
- printf(" %s", ip->name);
+ for (inp = list->first; inp; inp = inp->next)
+ printf(" %s", inp->initd->name);
printf("\n");
} else {
printf("%s list is empty\n", startstop);
diff --git a/test/tadd-deps2.c b/test/tadd-deps2.c
index c5c736d..a8da297 100644
--- a/test/tadd-deps2.c
+++ b/test/tadd-deps2.c
@@ -45,7 +45,7 @@ int main(int argc, char *argv[])
static void print_sk_list(const initd_list_t *list, initd_sk_t sk)
{
char *startstop;
- initd_t *ip;
+ initd_node_t *inp;
switch (sk) {
case SK_START:
@@ -61,8 +61,8 @@ static void print_sk_list(const initd_list_t *list, initd_sk_t sk)
if (list && list->first) {
printf("All deps for %s\n", startstop);
printf("Ordered:");
- for (ip = list->first; ip; ip = ip->next)
- printf(" %s", ip->name);
+ for (inp = list->first; inp; inp = inp->next)
+ printf(" %s", inp->initd->name);
printf("\n");
} else {
printf("%s list is empty\n", startstop);
diff --git a/test/tinitd-list.c b/test/tinitd-list.c
index 2d4c685..3778f5d 100644
--- a/test/tinitd-list.c
+++ b/test/tinitd-list.c
@@ -63,12 +63,12 @@ int main(int argc, char *argv[])
static void print_initd_list(initd_list_t *ilp)
{
- initd_t *cur;
+ initd_node_t *cur;
if (!ilp) {
printf("No initd list provided");
return;
}
printf("initd list contents:\n");
for (cur = ilp->first; cur; cur = cur->next)
- printf(" %s\n", cur->name);
+ printf(" %s\n", cur->initd->name);
}
diff --git a/test/tinstall.c b/test/tinstall.c
index 8fd26fa..ad1468d 100644
--- a/test/tinstall.c
+++ b/test/tinstall.c
@@ -50,7 +50,7 @@ int main(int argc, char *argv[])
static void print_sk_list(const initd_list_t *list, initd_sk_t sk)
{
char *startstop;
- initd_t *ip;
+ initd_node_t *inp;
switch (sk) {
case SK_START:
@@ -66,8 +66,8 @@ static void print_sk_list(const initd_list_t *list, initd_sk_t sk)
if (list && list->first) {
printf("All deps for %s\n", startstop);
printf("Ordered:");
- for (ip = list->first; ip; ip = ip->next)
- printf(" %s", ip->name);
+ for (inp = list->first; inp; inp = inp->next)
+ printf(" %s", inp->initd->name);
printf("\n");
} else {
printf("%s list is empty\n", startstop);
diff --git a/test/tparse-dir.c b/test/tparse-dir.c
index e3d24db..db052b3 100644
--- a/test/tparse-dir.c
+++ b/test/tparse-dir.c
@@ -22,9 +22,11 @@ int main(int argc, char *argv[])
static void print_list(const initd_list_t *list)
{
+ initd_node_t *inp;
initd_t *ip;
int n;
- for (ip = list->first; ip; ip = ip->next) {
+ for (inp = list->first; inp; inp = inp->next) {
+ ip = inp->initd;
printf("Service %s provides:", ip->name);
for (n = 0; n < prov_get_num(ip->prov); n++)
printf(" %s", prov_get_prov(ip->prov, n));
diff --git a/test/trem-deps.c b/test/trem-deps.c
index 676e9fe..070dec5 100644
--- a/test/trem-deps.c
+++ b/test/trem-deps.c
@@ -48,7 +48,7 @@ int main(int argc, char *argv[])
static void print_sk_list(const initd_list_t *list, initd_sk_t sk)
{
char *startstop;
- initd_t *ip;
+ initd_node_t *inp;
switch (sk) {
case SK_START:
@@ -64,8 +64,8 @@ static void print_sk_list(const initd_list_t *list, initd_sk_t sk)
if (list && list->first) {
printf("All deps for %s after removal\n", startstop);
printf("Ordered:");
- for (ip = list->first; ip; ip = ip->next)
- printf(" %s", ip->name);
+ for (inp = list->first; inp; inp = inp->next)
+ printf(" %s", inp->initd->name);
printf("\n");
} else {
printf("%s list is empty\n", startstop);
diff --git a/test/tremove.c b/test/tremove.c
index ebd595d..4c82122 100644
--- a/test/tremove.c
+++ b/test/tremove.c
@@ -52,7 +52,7 @@ int main(int argc, char *argv[])
static void print_sk_list(const initd_list_t *list, initd_sk_t sk)
{
char *startstop;
- initd_t *ip;
+ initd_node_t *inp;
switch (sk) {
case SK_START:
@@ -68,8 +68,8 @@ static void print_sk_list(const initd_list_t *list, initd_sk_t sk)
if (list && list->first) {
printf("All deps for %s\n", startstop);
printf("Ordered:");
- for (ip = list->first; ip; ip = ip->next)
- printf(" %s", ip->name);
+ for (inp = list->first; inp; inp = inp->next)
+ printf(" %s", inp->initd->name);
printf("\n");
} else {
printf("%s list is empty\n", startstop);