diff options
| author | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2017-01-29 15:37:23 +0000 | 
|---|---|---|
| committer | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2017-01-29 15:37:23 +0000 | 
| commit | 4150bf0c6aa6b2bdabb43a32a3e127ae3e50507d (patch) | |
| tree | eaf66f732f52d84a5daf3f6736b489c3a755a620 /src | |
| parent | 25ce65a8a4454fca6a4206a828caeb74d0599d86 (diff) | |
| parent | d6321a22f8c957523e7acbf6c57f5730b55ac378 (diff) | |
| download | ouroboros-4150bf0c6aa6b2bdabb43a32a3e127ae3e50507d.tar.gz ouroboros-4150bf0c6aa6b2bdabb43a32a3e127ae3e50507d.zip | |
Merged in dstaesse/ouroboros/be-rib (pull request #354)
lib: Add function to get children of node in RIB
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/rib.c | 67 | ||||
| -rw-r--r-- | src/lib/tests/rib_test.c | 24 | 
2 files changed, 91 insertions, 0 deletions
| diff --git a/src/lib/rib.c b/src/lib/rib.c index 4d1ae884..6b27ad27 100644 --- a/src/lib/rib.c +++ b/src/lib/rib.c @@ -95,6 +95,7 @@ struct rnode {          struct rnode *   parent; +        size_t           chlen;          struct list_head children;          struct list_head subs; @@ -248,6 +249,8 @@ static int rnode_add_child(struct rnode * node,          c->node = child;          list_add(&c->next, &node->children); +        ++node->chlen; +          return 0;  } @@ -265,6 +268,7 @@ static void rnode_remove_child(struct rnode * node,                  if (c->node == child) {                          list_del(&c->next);                          free(c); +                        --node->chlen;                          return;                  }          } @@ -321,6 +325,8 @@ static struct rnode * rnode_create(struct rnode *  parent,          node->parent = parent; +        node->chlen = 0; +          branch_hash(node);          rnode_throw_event(node, RO_CREATE); @@ -606,6 +612,13 @@ ssize_t rib_read(const char * path,                  return -EFBIG;          } +        if (node->data == NULL) { +                pthread_rwlock_unlock(&rib.lock); +                return 0; +        } + +        assert(node->len > 0); +          memcpy(data, node->data, node->len);          rlen = node->len; @@ -681,6 +694,60 @@ bool rib_has(const char * path)          return node != NULL;  } +ssize_t rib_children(const char * path, +                     char ***     children) +{ +        struct list_head * p; + +        struct rnode * node; + +        ssize_t i = 0; + +        assert(path); +        assert(children); + +        pthread_rwlock_rdlock(&rib.lock); + +        node = find_rnode_by_path(path); +        if (node == NULL) { +                pthread_rwlock_unlock(&rib.lock); +                return -EPERM; +        } + +        if (node->chlen == 0) { +                pthread_rwlock_unlock(&rib.lock); +                *children = NULL; +                return 0; +        } + +        *children = malloc(sizeof(**children) * node->chlen); +        if (*children == NULL) { +                pthread_rwlock_unlock(&rib.lock); +                return -ENOMEM; +        } + +        list_for_each(p, &node->children) { +                struct child * c = list_entry(p, struct child, next); +                (*children)[i] = strdup(c->node->name); +                if ((*children)[i] == NULL) { +                        ssize_t j; +                        pthread_rwlock_unlock(&rib.lock); +                        for (j = 0; j < i; ++j) +                                free((*children)[j]); +                        free(*children); +                        return -ENOMEM; +                } +                ++i; +        } + +        assert(i > 0); +        assert((size_t) i == node->chlen); + +        pthread_rwlock_unlock(&rib.lock); + +        return i; +} +  static struct rib_sub * rib_get_sub(uint32_t sid)  {          struct list_head * p; diff --git a/src/lib/tests/rib_test.c b/src/lib/tests/rib_test.c index 37503941..bad01083 100644 --- a/src/lib/tests/rib_test.c +++ b/src/lib/tests/rib_test.c @@ -46,6 +46,9 @@ int rib_test(int     argc,          char tmp[RIB_MAX_PATH_LEN]; +        char ** kids; +        ssize_t ch; +          struct timespec t = {0, 100 * BILLION};          (void) argc; @@ -73,6 +76,16 @@ int rib_test(int     argc,                  return -1;          } +        ch = rib_children("/static_info", &kids); +        if (ch != 0) { +                printf("Wrong number of children returned.\n"); +                rib_fini(); +                while (ch > 0) +                        free(kids[--ch]); +                free(kids); +                return -1; +        } +          if (!rib_has("/static_info")) {                  printf("Failed to find added element.\n");                  rib_fini(); @@ -118,6 +131,17 @@ int rib_test(int     argc,                  return -1;          } +        ch = rib_children("/static_info", &kids); +        if (ch != 2) { +                printf("Wrong number of children returned.\n"); +                rib_fini(); +                return -1; +        } + +        while (ch > 0) +                free(kids[--ch]); +        free(kids); +          if (addr_chk != addr_size) {                  printf("Failed to verify added element contents.\n");                  rib_fini(); | 
