--- libfshelp/Makefile | 3 +- libfshelp/fshelp.h | 21 ++++++ libfshelp/translator-list.c | 161 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 libfshelp/translator-list.c
diff --git a/libfshelp/Makefile b/libfshelp/Makefile index 4de3837..6ba6a14 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 cf39fbc..37f4e82 100644 --- a/libfshelp/fshelp.h +++ b/libfshelp/fshelp.h @@ -32,6 +32,27 @@ #include <maptime.h> +/* XXX */ +/* XXX */ + +/* XXX */ +error_t +fshelp_set_active_translator (const char *name, mach_port_t active); + +/* XXX */ +error_t +fshelp_remove_active_translator (mach_port_t active); + +/* XXX */ +typedef error_t (*fshelp_filter) (const char *path); + +/* XXX */ +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, returning the control port. They do not require multi threading diff --git a/libfshelp/translator-list.c b/libfshelp/translator-list.c new file mode 100644 index 0000000..a04f424 --- /dev/null +++ b/libfshelp/translator-list.c @@ -0,0 +1,161 @@ +/* + Copyright (C) 2013 Free Software Foundation + Written by Justus Winter <4win...@informatik.uni-hamburg.de> + + This file is part of the GNU Hurd. + + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <argz.h> +#include <hurd/fsys.h> +#include <hurd/ihash.h> +#include <mach.h> +#include <mach/notify.h> +#include <pthread.h> +#include <stdlib.h> +#include <string.h> + +#include "fshelp.h" + +struct translator +{ + char *name; + mach_port_t active; +}; + +/* XXX */ +static struct hurd_ihash translator_ihash + = HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP); + +static pthread_mutex_t translator_ihash_lock = PTHREAD_MUTEX_INITIALIZER; + +/* XXX */ +static void +translator_ihash_cleanup (void *element, void *arg) +{ + /* XXX: No need to deallocate port, we only keep a "weak" + reference. */ + free (element); +} + +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) + /* XXX: No need to increment the reference count, we only keep a + "weak" reference. */ + t->active = active; + else + hurd_ihash_remove (&translator_ihash, (hurd_ihash_key_t) t); + + out: + pthread_mutex_unlock (&translator_ihash_lock); + return err; +} + +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; +} + +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; +} -- 1.7.10.4