]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: introduce name_manager
authorMasatake YAMATO <yamato@redhat.com>
Fri, 7 May 2021 16:50:20 +0000 (01:50 +0900)
committerKarel Zak <kzak@redhat.com>
Wed, 6 Oct 2021 09:01:53 +0000 (11:01 +0200)
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
misc-utils/lsfd.c
misc-utils/lsfd.h

index 17a426f9d52ec68d3a356b98cf8610462902e537..cc6adc78ff5b58ddd91cff4ab0bf157e01e1c616 100644 (file)
@@ -1003,6 +1003,76 @@ int main(int argc, char *argv[])
        return 0;
 }
 
+struct name_manager {
+       struct idcache *cache;
+       pthread_rwlock_t rwlock;
+       unsigned long next_id;
+};
+
+struct name_manager *new_name_manager(void)
+{
+       struct name_manager *nm = xcalloc(1, sizeof(struct name_manager));
+       nm->cache = new_idcache();
+       if (!nm->cache)
+               err(EXIT_FAILURE, _("failed to allocate an idcache"));
+
+       pthread_rwlock_init(&nm->rwlock, NULL);
+       nm->next_id = 1;        /* 0 is never issued as id. */
+       return nm;
+}
+
+void free_name_manager(struct name_manager *nm)
+{
+       free_idcache(nm->cache);
+       free(nm);
+}
+
+const char *get_name(struct name_manager *nm, unsigned long id)
+{
+       struct identry *e;
+
+       pthread_rwlock_rdlock(&nm->rwlock);
+       e = get_id(nm->cache, id);
+       pthread_rwlock_unlock(&nm->rwlock);
+
+       return e? e->name: NULL;
+}
+
+unsigned long add_name(struct name_manager *nm, const char *name)
+{
+       struct identry *e = NULL, *tmp;
+
+       pthread_rwlock_rdlock(&nm->rwlock);
+       for (tmp = nm->cache->ent; tmp; tmp = tmp->next) {
+               if (strcmp(tmp->name, name) == 0) {
+                       e = tmp;
+                       break;
+               }
+       }
+       pthread_rwlock_unlock(&nm->rwlock);
+       if (e)
+               return e->id;
+
+       pthread_rwlock_wrlock(&nm->rwlock);
+       for (tmp = nm->cache->ent; tmp; tmp = tmp->next) {
+               if (strcmp(tmp->name, name) == 0) {
+                       e = tmp;
+                       break;
+               }
+       }
+
+       if (!e) {
+               e = xmalloc(sizeof(struct identry));
+               e->name = xstrdup(name);
+               e->id = nm->next_id++;
+               e->next = nm->cache->ent;
+               nm->cache->ent = e;
+       }
+       pthread_rwlock_unlock(&nm->rwlock);
+
+       return e->id;
+}
+
 DIR *opendirf(const char *format, ...)
 {
        va_list ap;
index 7862973adb9288de3fc13f0b0515e66e5d2d5ab1..c800e38f5938cd76c522ad7ca0ed352bf0507b25 100644 (file)
@@ -148,4 +148,14 @@ struct file *make_sock(const struct file_class *class,
 struct file *make_unkn(const struct file_class *class,
                       struct stat *sb, const char *name, int fd);
 
+/*
+ * Name managing
+ */
+struct name_manager;
+
+struct name_manager *new_name_manager(void);
+void free_name_manager(struct name_manager *nm);
+const char *get_name(struct name_manager *nm, unsigned long id);
+unsigned long add_name(struct name_manager *nm, const char *name);
+
 #endif /* UTIL_LINUX_LSFD_H */