summaryrefslogtreecommitdiff
path: root/procfs.c
diff options
context:
space:
mode:
authorJeremie Koenig <jk@jk.fr.eu.org>2010-08-17 09:43:29 +0000
committerJeremie Koenig <jk@jk.fr.eu.org>2010-08-30 14:14:42 +0200
commitd938e96e59a41d5eaa11040513815b757e58eb0c (patch)
tree38d1eb581cfeace88ebcd475b44f1a1459654392 /procfs.c
Basic infrastructure
* procfs.h: New file; basic interfaces for procfs nodes. * procfs.c: New file; implement the basic infrastructure. * netfs.c: New file; bridge libnetfs and the procfs interfaces. * main.c: New file; mostly a "Hello, World!" for now. * Makefile: New file; standalone for now.
Diffstat (limited to 'procfs.c')
-rw-r--r--procfs.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/procfs.c b/procfs.c
new file mode 100644
index 0000000..304befb
--- /dev/null
+++ b/procfs.c
@@ -0,0 +1,90 @@
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <hurd/netfs.h>
+#include <hurd/fshelp.h>
+#include "procfs.h"
+
+struct netnode
+{
+ const struct procfs_node_ops *ops;
+ void *hook;
+
+ /* (cached) contents of the node */
+ void *contents;
+ size_t contents_len;
+};
+
+struct node *procfs_make_node (const struct procfs_node_ops *ops, void *hook)
+{
+ struct netnode *nn;
+ struct node *np;
+
+ nn = malloc (sizeof *nn);
+ if (! nn)
+ return NULL;
+
+ memset (nn, 0, sizeof *nn);
+ nn->ops = ops;
+ nn->hook = hook;
+
+ np = netfs_make_node (nn);
+ if (! np)
+ {
+ free (nn);
+ return NULL;
+ }
+
+ np->nn = nn;
+ memset (&np->nn_stat, 0, sizeof np->nn_stat);
+ np->nn_translated = 0;
+
+ if (np->nn->ops->lookup)
+ np->nn_stat.st_mode = S_IFDIR | 0555;
+ else
+ np->nn_stat.st_mode = S_IFREG | 0444;
+
+ return np;
+}
+
+error_t procfs_get_contents (struct node *np, void **data, size_t *data_len)
+{
+ if (! np->nn->contents && np->nn->ops->get_contents)
+ {
+ void *contents;
+ size_t contents_len;
+ error_t err;
+
+ err = np->nn->ops->get_contents (np->nn->hook, &contents, &contents_len);
+ if (err)
+ return err;
+
+ np->nn->contents = contents;
+ np->nn->contents_len = contents_len;
+ }
+
+ *data = np->nn->contents;
+ *data_len = np->nn->contents_len;
+ return 0;
+}
+
+error_t procfs_lookup (struct node *np, const char *name, struct node **npp)
+{
+ error_t err = ENOENT;
+
+ if (np->nn->ops->lookup)
+ err = np->nn->ops->lookup (np->nn->hook, name, npp);
+
+ return err;
+}
+
+void procfs_cleanup (struct node *np)
+{
+ if (np->nn->contents && np->nn->ops->cleanup_contents)
+ np->nn->ops->cleanup_contents (np->nn->contents);
+
+ if (np->nn->ops->cleanup)
+ np->nn->ops->cleanup (np->nn->hook);
+
+ free (np->nn);
+}