summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremie Koenig <jk@jk.fr.eu.org>2010-08-17 20:34:58 +0000
committerJeremie Koenig <jk@jk.fr.eu.org>2010-08-30 14:14:49 +0200
commitc62d5ff73ceaad21bb0784ed6098d307a625b10d (patch)
treed0998f7ffedb97bee2fe4f06bb6541a28bed4d20
parentba139824fa06a97f2a3b1cc4c6085d10a83ec2b9 (diff)
Add real process nodes
* process.c, process.h: New files, implement a process directory with cmdline and environ files. * Makefile: Add the process module. * proclist.c: Replace stub pid files with the real thing.
-rw-r--r--Makefile2
-rw-r--r--process.c79
-rw-r--r--process.h2
-rw-r--r--proclist.c13
4 files changed, 92 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index 1fe7415..23815d7 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
TARGET = procfs
-OBJS = procfs.o netfs.o procfs_file.o procfs_dir.o proclist.o main.o
+OBJS = procfs.o netfs.o procfs_file.o procfs_dir.o process.o proclist.o main.o
LIBS = -lnetfs
CC = gcc
diff --git a/process.c b/process.c
new file mode 100644
index 0000000..90ea511
--- /dev/null
+++ b/process.c
@@ -0,0 +1,79 @@
+#include <stdlib.h>
+#include <hurd/process.h>
+#include "procfs.h"
+#include "procfs_dir.h"
+#include "process.h"
+
+struct process_node {
+ process_t procserv;
+ pid_t pid;
+};
+
+
+/* The proc_getprocargs() and proc_getprocenv() calls have the same
+ prototype and we use them in the same way; namely, publish the data
+ they return as-is. We take advantage of this to have common code and
+ use a function pointer as the procfs_dir "entry hook" to choose the
+ call to use on a file by file basis. */
+
+struct process_argz_node
+{
+ struct process_node pn;
+ error_t (*getargz) (process_t, pid_t, void **, mach_msg_type_number_t *);
+};
+
+static error_t
+process_argz_get_contents (void *hook, void **contents, size_t *contents_len)
+{
+ struct process_argz_node *pz = hook;
+ error_t err;
+
+ *contents_len = 0;
+ err = pz->getargz (pz->pn.procserv, pz->pn.pid, contents, contents_len);
+ if (err)
+ return EIO;
+
+ return 0;
+}
+
+static struct node *
+process_argz_make_node (void *dir_hook, void *entry_hook)
+{
+ static const struct procfs_node_ops ops = {
+ .get_contents = process_argz_get_contents,
+ .cleanup_contents = procfs_cleanup_contents_with_vm_deallocate,
+ .cleanup = free,
+ };
+ struct process_argz_node *zn;
+
+ zn = malloc (sizeof *zn);
+ if (! zn)
+ return NULL;
+
+ memcpy (&zn->pn, dir_hook, sizeof zn->pn);
+ zn->getargz = entry_hook;
+
+ return procfs_make_node (&ops, zn);
+}
+
+
+struct node *
+process_make_node (process_t procserv, pid_t pid)
+{
+ static const struct procfs_dir_entry entries[] = {
+ { "cmdline", process_argz_make_node, proc_getprocargs, },
+ { "environ", process_argz_make_node, proc_getprocenv, },
+ { NULL, }
+ };
+ struct process_node *pn;
+
+ pn = malloc (sizeof *pn);
+ if (! pn)
+ return NULL;
+
+ pn->procserv = procserv;
+ pn->pid = pid;
+
+ return procfs_dir_make_node (entries, pn, free);
+}
+
diff --git a/process.h b/process.h
new file mode 100644
index 0000000..8ca7c85
--- /dev/null
+++ b/process.h
@@ -0,0 +1,2 @@
+struct node *
+process_make_node (process_t procserv, pid_t pid);
diff --git a/proclist.c b/proclist.c
index e009ebd..148e4bc 100644
--- a/proclist.c
+++ b/proclist.c
@@ -4,8 +4,7 @@
#include <mach.h>
#include <hurd/process.h>
#include "procfs.h"
-#include "procfs_file.h"
-#include "procfs_dir.h"
+#include "process.h"
#define PID_STR_SIZE (3 * sizeof (pid_t) + 1)
@@ -49,7 +48,15 @@ proclist_get_contents (void *hook, void **contents, size_t *contents_len)
static error_t
proclist_lookup (void *hook, const char *name, struct node **np)
{
- *np = procfs_file_make_node ("Ceci n'est pas un processus\n", -1, NULL);
+ struct proclist_node *pl = hook;
+ char *endp;
+ pid_t pid;
+
+ pid = strtol (name, &endp, 10);
+ if (name[0] == '0' || !name[0] || *endp)
+ return ENOENT;
+
+ *np = process_make_node (pl->process, pid);
return *np ? 0 : ENOMEM;
}