diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-09-18 19:38:04 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-09-29 12:38:36 +0200 |
commit | b288ae932a53133c986e5daace2d5bfa4cf95d2c (patch) | |
tree | 21342c6bf2ed5d1c1d8a5b63de1595ec26eb2002 | |
parent | e9b7aa85c98750b6c8f54f3eb0013c359841f4d4 (diff) |
procfs: implement /proc/filesystems
* procfs/rootdir.c (rootdir_gc_filesystems): New function.
(rootdir_entries): Use the new function to implement /proc/filesystems.
-rw-r--r-- | procfs/rootdir.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/procfs/rootdir.c b/procfs/rootdir.c index 95410598..f92e73d2 100644 --- a/procfs/rootdir.c +++ b/procfs/rootdir.c @@ -1,5 +1,5 @@ /* Hurd /proc filesystem, permanent files of the root directory. - Copyright (C) 2010,13 Free Software Foundation, Inc. + Copyright (C) 2010,13,14 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -32,6 +32,7 @@ #include <sys/stat.h> #include <argz.h> #include <ps.h> +#include <glob.h> #include "procfs.h" #include "procfs_dir.h" #include "main.h" @@ -532,6 +533,57 @@ rootdir_gc_slabinfo (void *hook, char **contents, ssize_t *contents_len) cache_info, cache_info_count * sizeof *cache_info); return err; } + +static error_t +rootdir_gc_filesystems (void *hook, char **contents, ssize_t *contents_len) +{ + error_t err = 0; + size_t i; + int glob_ret; + glob_t matches; + FILE *m; + + m = open_memstream (contents, contents_len); + if (m == NULL) + return errno; + + glob_ret = glob (_HURD "*fs", 0, NULL, &matches); + switch (glob_ret) + { + case 0: + for (i = 0; i < matches.gl_pathc; i++) + { + /* Get ith entry, shave off the prefix. */ + char *name = &matches.gl_pathv[i][sizeof _HURD - 1]; + + /* Linux naming convention is a bit inconsistent. */ + if (strncmp (name, "ext", 3) == 0 + || strcmp (name, "procfs") == 0) + /* Drop the fs suffix. */ + name[strlen (name) - 2] = 0; + + fprintf (m, "\t%s\n", name); + } + + globfree (&matches); + break; + + case GLOB_NOMATCH: + /* Poor fellow. */ + break; + + case GLOB_NOSPACE: + err = ENOMEM; + break; + + default: + /* This should not happen. */ + err = EGRATUITOUS; + } + + fclose (m); + return err; +} /* Glue logic and entries table */ @@ -632,6 +684,13 @@ static const struct procfs_dir_entry rootdir_entries[] = { .cleanup_contents = procfs_cleanup_contents_with_free, }, }, + { + .name = "filesystems", + .hook = & (struct procfs_node_ops) { + .get_contents = rootdir_gc_filesystems, + .cleanup_contents = procfs_cleanup_contents_with_free, + }, + }, #ifdef PROFILE /* In order to get a usable gmon.out file, we must apparently use exit(). */ { |