From 9df906ee4f34cf54c9ba253d44abb74b0ef63fe1 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Tue, 30 Jul 2013 11:59:13 +0200 Subject: libfshelp: add translator-list.c Add functions that maintain a list of active translators. * libfshelp/translator-list.c: New file. * libfshelp/fshelp.h: Add function declarations. * libfshelp/Makefile: Add translator-list.c, link against libihash. --- libfshelp/Makefile | 3 +- libfshelp/fshelp.h | 33 ++++++++- libfshelp/translator-list.c | 169 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 libfshelp/translator-list.c (limited to 'libfshelp') diff --git a/libfshelp/Makefile b/libfshelp/Makefile index 4de38372..6ba6a14f 100644 --- a/libfshelp/Makefile +++ b/libfshelp/Makefile @@ -20,6 +20,7 @@ makemode := library libname = libfshelp SRCS = lock-acquire.c lock-init.c \ + translator-list.c \ start-translator-long.c start-translator.c \ fetch-root.c transbox-init.c set-active.c fetch-control.c \ drop-transbox.c translated.c \ @@ -32,7 +33,7 @@ SRCS = lock-acquire.c lock-init.c \ touch.c installhdrs = fshelp.h -HURDLIBS = shouldbeinlibc iohelp ports +HURDLIBS = shouldbeinlibc iohelp ports ihash LDLIBS += -lpthread OBJS = $(subst .c,.o,$(SRCS)) diff --git a/libfshelp/fshelp.h b/libfshelp/fshelp.h index cf39fbc4..43fbcd78 100644 --- a/libfshelp/fshelp.h +++ b/libfshelp/fshelp.h @@ -1,5 +1,6 @@ /* FS helper library definitions - Copyright (C) 1994,95,96,97,98,99,2000,01,02 Free Software Foundation, Inc. + Copyright (C) 1994,95,96,97,98,99,2000,01,02,13 + Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -31,6 +32,36 @@ #include #include + +/* Keeping track of active translators */ +/* These routines keep a list of active translators. They are + self-contained and do not require multi threading or the ports + library. */ + +/* Record an active translator being bound to the given file name + NAME. ACTIVE is the control port of the translator. */ +error_t +fshelp_set_active_translator (const char *name, mach_port_t active); + +/* Remove the active translator specified by its control port ACTIVE. + If there is no active translator with the given control port, this + does nothing. */ +error_t +fshelp_remove_active_translator (mach_port_t active); + +/* This kind of function is used by fshelp_get_active_translators to + filter the list of translators to return. If a filter returns an + error for a given PATH, the translator bound to the PATH is not + included in the list. */ +typedef error_t (*fshelp_filter) (const char *path); + +/* Records the list of active translators into the argz vector + specified by TRANSLATORS filtered by FILTER. */ +error_t +fshelp_get_active_translators (char **translators, + size_t *translators_len, + fshelp_filter filter); + /* Passive translator linkage */ /* These routines are self-contained and start passive translators, diff --git a/libfshelp/translator-list.c b/libfshelp/translator-list.c new file mode 100644 index 00000000..a24d9762 --- /dev/null +++ b/libfshelp/translator-list.c @@ -0,0 +1,169 @@ +/* A list of active translators. + + Copyright (C) 2013 Free Software Foundation, Inc. + + Written by Justus Winter <4winter@informatik.uni-hamburg.de> + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the GNU Hurd. If not, see . */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fshelp.h" + +struct translator +{ + char *name; + mach_port_t active; +}; + +/* The list of active translators. */ +static struct hurd_ihash translator_ihash + = HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP); + +/* The lock protecting the translator_ihash. */ +static pthread_mutex_t translator_ihash_lock = PTHREAD_MUTEX_INITIALIZER; + +static void +translator_ihash_cleanup (void *element, void *arg) +{ + /* No need to deallocate port, we only keep the name of the + port, not a reference. */ + free (element); +} + +/* Record an active translator being bound to the given file name + NAME. ACTIVE is the control port of the translator. */ +error_t +fshelp_set_active_translator (const char *name, mach_port_t active) +{ + error_t err = 0; + pthread_mutex_lock (&translator_ihash_lock); + + if (! translator_ihash.cleanup) + hurd_ihash_set_cleanup (&translator_ihash, translator_ihash_cleanup, NULL); + + struct translator *t = NULL; + HURD_IHASH_ITERATE (&translator_ihash, value) + { + t = value; + if (strcmp (name, t->name) == 0) + goto update; /* Entry exists. */ + } + + t = malloc (sizeof (struct translator)); + if (! t) + return ENOMEM; + + t->active = MACH_PORT_NULL; + t->name = strdup (name); + if (! t->name) + { + err = errno; + free (t); + goto out; + } + + err = hurd_ihash_add (&translator_ihash, (hurd_ihash_key_t) t, t); + if (err) + goto out; + + update: + if (active) + /* No need to increment the reference count, we only keep the + name, not a reference. */ + t->active = active; + else + hurd_ihash_remove (&translator_ihash, (hurd_ihash_key_t) t); + + out: + pthread_mutex_unlock (&translator_ihash_lock); + return err; +} + +/* Remove the active translator specified by its control port ACTIVE. + If there is no active translator with the given control port, this + does nothing. */ +error_t +fshelp_remove_active_translator (mach_port_t active) +{ + error_t err = 0; + pthread_mutex_lock (&translator_ihash_lock); + + struct translator *t = NULL; + HURD_IHASH_ITERATE (&translator_ihash, value) + { + struct translator *v = value; + if (active == v->active) + { + t = v; + break; + } + } + + if (t) + hurd_ihash_remove (&translator_ihash, (hurd_ihash_key_t) t); + + pthread_mutex_unlock (&translator_ihash_lock); + return err; +} + +/* Records the list of active translators into the argz vector + specified by TRANSLATORS filtered by FILTER. */ +error_t +fshelp_get_active_translators (char **translators, + size_t *translators_len, + fshelp_filter filter) +{ + error_t err = 0; + pthread_mutex_lock (&translator_ihash_lock); + + HURD_IHASH_ITERATE (&translator_ihash, value) + { + struct translator *t = value; + if (filter) + { + char *dir = strdup (t->name); + if (! dir) + { + err = ENOMEM; + break; + } + + err = filter (dirname (dir)); + free (dir); + if (err) + { + err = 0; + continue; /* Skip this entry. */ + } + } + + err = argz_add (translators, translators_len, + t->name); + if (err) + break; + } + + pthread_mutex_unlock (&translator_ihash_lock); + return err; +} -- cgit v1.2.3