The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/cmd/zed/zed_strings.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * This file is part of the ZFS Event Daemon (ZED).
    3  *
    4  * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049).
    5  * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
    6  * Refer to the OpenZFS git commit log for authoritative copyright attribution.
    7  *
    8  * The contents of this file are subject to the terms of the
    9  * Common Development and Distribution License Version 1.0 (CDDL-1.0).
   10  * You can obtain a copy of the license from the top-level file
   11  * "OPENSOLARIS.LICENSE" or at <http://opensource.org/licenses/CDDL-1.0>.
   12  * You may not use this file except in compliance with the license.
   13  */
   14 
   15 #include <assert.h>
   16 #include <errno.h>
   17 #include <stddef.h>
   18 #include <stdlib.h>
   19 #include <string.h>
   20 #include <sys/avl.h>
   21 #include <sys/sysmacros.h>
   22 #include "zed_strings.h"
   23 
   24 struct zed_strings {
   25         avl_tree_t tree;
   26         avl_node_t *iteratorp;
   27 };
   28 
   29 struct zed_strings_node {
   30         avl_node_t node;
   31         char *key;
   32         char *val;
   33 };
   34 
   35 typedef struct zed_strings_node zed_strings_node_t;
   36 
   37 /*
   38  * Compare zed_strings_node_t nodes [x1] and [x2].
   39  * As required for the AVL tree, return -1 for <, 0 for ==, and +1 for >.
   40  */
   41 static int
   42 _zed_strings_node_compare(const void *x1, const void *x2)
   43 {
   44         const char *s1;
   45         const char *s2;
   46         int rv;
   47 
   48         assert(x1 != NULL);
   49         assert(x2 != NULL);
   50 
   51         s1 = ((const zed_strings_node_t *) x1)->key;
   52         assert(s1 != NULL);
   53         s2 = ((const zed_strings_node_t *) x2)->key;
   54         assert(s2 != NULL);
   55         rv = strcmp(s1, s2);
   56 
   57         if (rv < 0)
   58                 return (-1);
   59 
   60         if (rv > 0)
   61                 return (1);
   62 
   63         return (0);
   64 }
   65 
   66 /*
   67  * Return a new string container, or NULL on error.
   68  */
   69 zed_strings_t *
   70 zed_strings_create(void)
   71 {
   72         zed_strings_t *zsp;
   73 
   74         zsp = calloc(1, sizeof (*zsp));
   75         if (!zsp)
   76                 return (NULL);
   77 
   78         avl_create(&zsp->tree, _zed_strings_node_compare,
   79             sizeof (zed_strings_node_t), offsetof(zed_strings_node_t, node));
   80 
   81         zsp->iteratorp = NULL;
   82         return (zsp);
   83 }
   84 
   85 /*
   86  * Destroy the string node [np].
   87  */
   88 static void
   89 _zed_strings_node_destroy(zed_strings_node_t *np)
   90 {
   91         if (!np)
   92                 return;
   93 
   94         if (np->key) {
   95                 if (np->key != np->val)
   96                         free(np->key);
   97                 np->key = NULL;
   98         }
   99         if (np->val) {
  100                 free(np->val);
  101                 np->val = NULL;
  102         }
  103         free(np);
  104 }
  105 
  106 /*
  107  * Return a new string node for storing the string [val], or NULL on error.
  108  * If [key] is specified, it will be used to index the node; otherwise,
  109  * the string [val] will be used.
  110  */
  111 static zed_strings_node_t *
  112 _zed_strings_node_create(const char *key, const char *val)
  113 {
  114         zed_strings_node_t *np;
  115 
  116         assert(val != NULL);
  117 
  118         np = calloc(1, sizeof (*np));
  119         if (!np)
  120                 return (NULL);
  121 
  122         np->val = strdup(val);
  123         if (!np->val)
  124                 goto nomem;
  125 
  126         if (key) {
  127                 np->key = strdup(key);
  128                 if (!np->key)
  129                         goto nomem;
  130         } else {
  131                 np->key = np->val;
  132         }
  133         return (np);
  134 
  135 nomem:
  136         _zed_strings_node_destroy(np);
  137         return (NULL);
  138 }
  139 
  140 /*
  141  * Destroy the string container [zsp] and all nodes within.
  142  */
  143 void
  144 zed_strings_destroy(zed_strings_t *zsp)
  145 {
  146         void *cookie;
  147         zed_strings_node_t *np;
  148 
  149         if (!zsp)
  150                 return;
  151 
  152         cookie = NULL;
  153         while ((np = avl_destroy_nodes(&zsp->tree, &cookie)))
  154                 _zed_strings_node_destroy(np);
  155 
  156         avl_destroy(&zsp->tree);
  157         free(zsp);
  158 }
  159 
  160 /*
  161  * Add a copy of the string [s] indexed by [key] to the container [zsp].
  162  * If [key] already exists within the container [zsp], it will be replaced
  163  * with the new string [s].
  164  * If [key] is NULL, the string [s] will be used as the key.
  165  * Return 0 on success, or -1 on error.
  166  */
  167 int
  168 zed_strings_add(zed_strings_t *zsp, const char *key, const char *s)
  169 {
  170         zed_strings_node_t *newp, *oldp;
  171 
  172         if (!zsp || !s) {
  173                 errno = EINVAL;
  174                 return (-1);
  175         }
  176         if (key == s)
  177                 key = NULL;
  178 
  179         newp = _zed_strings_node_create(key, s);
  180         if (!newp)
  181                 return (-1);
  182 
  183         oldp = avl_find(&zsp->tree, newp, NULL);
  184         if (oldp) {
  185                 avl_remove(&zsp->tree, oldp);
  186                 _zed_strings_node_destroy(oldp);
  187         }
  188         avl_add(&zsp->tree, newp);
  189         return (0);
  190 }
  191 
  192 /*
  193  * Return the first string in container [zsp].
  194  * Return NULL if there are no strings, or on error.
  195  * This can be called multiple times to re-traverse [zsp].
  196  * XXX: Not thread-safe.
  197  */
  198 const char *
  199 zed_strings_first(zed_strings_t *zsp)
  200 {
  201         if (!zsp) {
  202                 errno = EINVAL;
  203                 return (NULL);
  204         }
  205         zsp->iteratorp = avl_first(&zsp->tree);
  206         if (!zsp->iteratorp)
  207                 return (NULL);
  208 
  209         return (((zed_strings_node_t *)zsp->iteratorp)->val);
  210 
  211 }
  212 
  213 /*
  214  * Return the next string in container [zsp].
  215  * Return NULL after the last string, or on error.
  216  * This must be called after zed_strings_first().
  217  * XXX: Not thread-safe.
  218  */
  219 const char *
  220 zed_strings_next(zed_strings_t *zsp)
  221 {
  222         if (!zsp) {
  223                 errno = EINVAL;
  224                 return (NULL);
  225         }
  226         if (!zsp->iteratorp)
  227                 return (NULL);
  228 
  229         zsp->iteratorp = AVL_NEXT(&zsp->tree, zsp->iteratorp);
  230         if (!zsp->iteratorp)
  231                 return (NULL);
  232 
  233         return (((zed_strings_node_t *)zsp->iteratorp)->val);
  234 }
  235 
  236 /*
  237  * Return the number of strings in container [zsp], or -1 on error.
  238  */
  239 int
  240 zed_strings_count(zed_strings_t *zsp)
  241 {
  242         if (!zsp) {
  243                 errno = EINVAL;
  244                 return (-1);
  245         }
  246         return (avl_numnodes(&zsp->tree));
  247 }

Cache object: d58e925e087806aa2620cd9aba655fd3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.