summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/hal/hald-runner/main.c68
-rw-r--r--usr/src/cmd/hal/hald-runner/runner.c49
-rw-r--r--usr/src/cmd/hal/hald-runner/runner.h5
3 files changed, 89 insertions, 33 deletions
diff --git a/usr/src/cmd/hal/hald-runner/main.c b/usr/src/cmd/hal/hald-runner/main.c
index cd2b866eda..accb65d875 100644
--- a/usr/src/cmd/hal/hald-runner/main.c
+++ b/usr/src/cmd/hal/hald-runner/main.c
@@ -4,6 +4,7 @@
* main.c - Main dbus interface of the hald runner
*
* Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net>
+ * Copyright (C) 2007 Codethink Ltd. Author Rob Taylor <rob.taylor@codethink.co.uk>
*
* Licensed under the Academic Free License version 2.1
*
@@ -31,24 +32,46 @@
#include "utils.h"
#include "runner.h"
+#ifndef __GNUC__
+#define __attribute__(x)
+#endif
+
static gboolean
-parse_first_part(run_request *r, DBusMessage *msg, DBusMessageIter *iter)
+parse_udi (run_request *r, DBusMessage *msg, DBusMessageIter *iter)
{
- DBusMessageIter sub_iter;
char *tmpstr;
- /* First should be the device UDI */
+ /* Should be the device UDI */
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING)
goto malformed;
dbus_message_iter_get_basic(iter, &tmpstr);
r->udi = g_strdup(tmpstr);
- /* Then the environment array */
- if (!dbus_message_iter_next(iter) || dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ if (!dbus_message_iter_next(iter))
+ goto malformed;
+
+ return TRUE;
+
+malformed:
+ return FALSE;
+}
+
+static gboolean
+parse_environment(run_request *r, DBusMessage *msg, DBusMessageIter *iter)
+{
+ DBusMessageIter sub_iter;
+ char *tmpstr;
+
+ /* The environment array */
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
goto malformed;
dbus_message_iter_recurse(iter, &sub_iter);
/* Add default path for the programs we start */
+#if defined(__FreeBSD__)
+ tmpstr = g_strdup_printf("PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/X11R6/sbin:/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:%s", getenv("PATH"));
+#else
tmpstr = g_strdup_printf("PATH=/sbin:/usr/sbin:/bin:/usr/bin:%s", getenv("PATH"));
+#endif
r->environment = get_string_array(&sub_iter, tmpstr);
/* Then argv */
@@ -74,7 +97,10 @@ handle_run(DBusConnection *con, DBusMessage *msg)
r = new_run_request();
g_assert(dbus_message_iter_init(msg, &iter));
- if (!parse_first_part(r, msg, &iter))
+ if (!parse_udi(r, msg, &iter))
+ goto malformed;
+
+ if (!parse_environment(r, msg, &iter))
goto malformed;
/* Next a string of what should be written to stdin */
@@ -106,25 +132,36 @@ malformed:
}
static void
-handle_start(DBusConnection *con, DBusMessage *msg)
+handle_start(DBusConnection *con, DBusMessage *msg, gboolean is_singleton)
{
DBusMessage *reply;
DBusMessageIter iter;
run_request *r;
GPid pid;
- dbus_int64_t pid64;
r = new_run_request();
+ r->is_singleton = is_singleton;
+
g_assert(dbus_message_iter_init(msg, &iter));
- if (!dbus_message_iter_init(msg, &iter) || !parse_first_part(r, msg, &iter))
+ if (!dbus_message_iter_init(msg, &iter))
goto malformed;
+ if (!is_singleton && !parse_udi(r, msg, &iter)) {
+ fprintf(stderr, "error parsing udi");
+ goto malformed;
+ }
+
+ if (!parse_environment(r, msg, &iter)) {
+ fprintf(stderr, "error parsing environment");
+ goto malformed;
+ }
+
if (run_request_run(r, con, NULL, &pid)) {
- pid64 = pid;
+ gint64 ppid = pid;
reply = dbus_message_new_method_return(msg);
dbus_message_append_args (reply,
- DBUS_TYPE_INT64, &pid64,
+ DBUS_TYPE_INT64, &ppid,
DBUS_TYPE_INVALID);
} else {
@@ -177,11 +214,18 @@ filter(DBusConnection *con, DBusMessage *msg, void *user_data)
handle_run(con, msg);
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Start")) {
- handle_start(con, msg);
+ handle_start(con, msg, FALSE);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ } else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "StartSingleton")) {
+ handle_start(con, msg, TRUE);
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Kill")) {
handle_kill(con, msg);
return DBUS_HANDLER_RESULT_HANDLED;
+ } else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Shutdown")) {
+ run_kill_all ();
+ exit (0);
+ return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "KillAll")) {
run_kill_all();
/* alwasy successfull */
diff --git a/usr/src/cmd/hal/hald-runner/runner.c b/usr/src/cmd/hal/hald-runner/runner.c
index a4a9aafd69..2d0f858b66 100644
--- a/usr/src/cmd/hal/hald-runner/runner.c
+++ b/usr/src/cmd/hal/hald-runner/runner.c
@@ -4,6 +4,7 @@
* runner.c - Process running code
*
* Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net>
+ * Copyright (C) 2007 Codethink Ltd. Author Rob Taylor <rob.taylor@codethink.co.uk>
*
* Licensed under the Academic Free License version 2.1
*
@@ -48,6 +49,7 @@
#define HALD_RUN_KILLED 0x4
GHashTable *udi_hash = NULL;
+GList *singletons = NULL;
typedef struct {
run_request *r;
@@ -128,15 +130,19 @@ send_reply(DBusConnection *con, DBusMessage *msg, guint32 exit_type, gint32 retu
}
static void
-remove_from_hash_table(run_data *rd)
+remove_run_data(run_data *rd)
{
GList *list;
- /* Remove to the hashtable */
- list = (GList *)g_hash_table_lookup(udi_hash, rd->r->udi);
- list = g_list_remove(list, rd);
- /* The hash table will take care to not leak the dupped string */
- g_hash_table_insert(udi_hash, g_strdup(rd->r->udi), list);
+ if (rd->r->is_singleton) {
+ singletons = g_list_remove(singletons, rd);
+ } else {
+ /* Remove to the hashtable */
+ list = (GList *)g_hash_table_lookup(udi_hash, rd->r->udi);
+ list = g_list_remove(list, rd);
+ /* The hash table will take care to not leak the dupped string */
+ g_hash_table_insert(udi_hash, g_strdup(rd->r->udi), list);
+ }
}
static void
@@ -145,7 +151,8 @@ run_exited(GPid pid, gint status, gpointer data)
run_data *rd = (run_data *)data;
char **error = NULL;
- printf("%s exited\n", rd->r->argv[0]);
+ printf("pid %d: rc=%d signaled=%d: %s\n",
+ pid, WEXITSTATUS(status), WIFSIGNALED(status), rd->r->argv[0]);
rd->watch = 0;
if (rd->sent_kill == TRUE) {
/* We send it a kill, so ignore */
@@ -170,18 +177,17 @@ run_exited(GPid pid, gint status, gpointer data)
free_string_array(error);
out:
- remove_from_hash_table(rd);
+ remove_run_data (rd);
/* emit a signal that this PID exited */
if(rd->con != NULL && rd->emit_pid_exited) {
DBusMessage *signal;
- dbus_int64_t pid64;
+ gint64 ppid = rd->pid;
signal = dbus_message_new_signal ("/org/freedesktop/HalRunner",
"org.freedesktop.HalRunner",
"StartedProcessExited");
- pid64 = rd->pid;
dbus_message_append_args (signal,
- DBUS_TYPE_INT64, &pid64,
+ DBUS_TYPE_INT64, &(ppid),
DBUS_TYPE_INVALID);
dbus_connection_send(rd->con, signal, NULL);
}
@@ -202,7 +208,7 @@ run_timedout(gpointer data) {
rd->sent_kill = TRUE;
send_reply(rd->con, rd->msg, HALD_RUN_TIMEOUT, 0, NULL);
- remove_from_hash_table(rd);
+ remove_run_data (rd);
return FALSE;
}
@@ -246,7 +252,7 @@ run_request_run (run_request *r, DBusConnection *con, DBusMessage *msg, GPid *ou
char *program_dir = NULL;
GList *list;
- printf("Run started %s (%d) (%d) \n!", r->argv[0], r->timeout,
+ printf("Run started %s (%u) (%d) \n!", r->argv[0], r->timeout,
r->error_on_stderr);
if (r->input != NULL) {
stdin_p = &stdin_v;
@@ -277,7 +283,7 @@ run_request_run (run_request *r, DBusConnection *con, DBusMessage *msg, GPid *ou
if (r->input) {
if (write(stdin_v, r->input, strlen(r->input)) != (ssize_t) strlen(r->input))
- printf("Warning: Error while wite r->input (%s) to stdin_v.\n", r->input);
+ printf("Warning: Error while writing r->input (%s) to stdin_v.\n", r->input);
close(stdin_v);
}
@@ -302,12 +308,16 @@ run_request_run (run_request *r, DBusConnection *con, DBusMessage *msg, GPid *ou
else
rd->timeout = 0;
- /* Add to the hashtable */
- list = (GList *)g_hash_table_lookup(udi_hash, r->udi);
- list = g_list_prepend(list, rd);
+ if (r->is_singleton) {
+ singletons = g_list_prepend(singletons, rd);
+ } else {
+ /* Add to the hashtable */
+ list = (GList *)g_hash_table_lookup(udi_hash, r->udi);
+ list = g_list_prepend(list, rd);
- /* The hash table will take care to not leak the dupped string */
- g_hash_table_insert(udi_hash, g_strdup(r->udi), list);
+ /* The hash table will take care to not leak the dupped string */
+ g_hash_table_insert(udi_hash, g_strdup(r->udi), list);
+ }
/* send back PID if requested.. and only emit StartedProcessExited in this case */
if (out_pid != NULL) {
@@ -365,6 +375,7 @@ void
run_kill_all()
{
g_hash_table_foreach_remove(udi_hash, hash_kill_udi, NULL);
+ g_list_foreach(singletons, kill_rd, NULL);
}
void
diff --git a/usr/src/cmd/hal/hald-runner/runner.h b/usr/src/cmd/hal/hald-runner/runner.h
index 2a18f941e3..d063784639 100644
--- a/usr/src/cmd/hal/hald-runner/runner.h
+++ b/usr/src/cmd/hal/hald-runner/runner.h
@@ -36,6 +36,7 @@ typedef struct {
gchar **argv;
gchar *input;
gboolean error_on_stderr;
+ gboolean is_singleton;
guint32 timeout;
} run_request;
@@ -49,9 +50,9 @@ gboolean run_request_run(run_request *r, DBusConnection *con, DBusMessage *msg,
void run_kill_udi(gchar *udi);
/* Kill all running request*/
-void run_kill_all();
+void run_kill_all(void);
/* initialise the actual runner data */
-void run_init();
+void run_init(void);
#endif /* RUNNER_H */