diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/hal/hald-runner/main.c | 68 | ||||
-rw-r--r-- | usr/src/cmd/hal/hald-runner/runner.c | 49 | ||||
-rw-r--r-- | usr/src/cmd/hal/hald-runner/runner.h | 5 |
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 */ |