[PATCH 1/4] add hald-runner support for singleton addons
Rob Taylor
rob.taylor at codethink.co.uk
Fri Jun 1 03:48:29 PDT 2007
Introduces a new method StartSingleton on org.freedesktop.HalRunner. This
takes one parameter of an array of strings for the environment to launch the
singleton. hald-runner keeps a list of running singletons, which are killable
only by KillAll.
The patch also adds hald_runner_start_singleton for starting a singleton.
---
hald-runner/main.c | 51 +++++++++++++++++++++++++++------
hald-runner/runner.c | 17 ++++++++---
hald-runner/runner.h | 1 +
hald/hald_runner.c | 78 +++++++++++++++++++++++++++++++++++++------------
hald/hald_runner.h | 7 ++++
5 files changed, 121 insertions(+), 33 deletions(-)
diff --git a/hald-runner/main.c b/hald-runner/main.c
index 3b170b3..f767b9b 100644
--- a/hald-runner/main.c
+++ b/hald-runner/main.c
@@ -4,6 +4,7 @@
* main.c - Main dbus interface of the hald runner
*
* Copyright (C) 2006 Sjoerd Simons, <sjoerd at luon.net>
+ * Copyright (C) 2007 Codethink Ltd. Author Rob Taylor <rob.taylor at codethink.co.uk>
*
* Licensed under the Academic Free License version 2.1
*
@@ -36,19 +37,33 @@
#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 */
@@ -82,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 */
@@ -114,7 +132,7 @@ malformed:
}
static void
-handle_start(DBusConnection *con, DBusMessage *msg)
+handle_start(DBusConnection *con, DBusMessage *msg, gboolean is_singleton)
{
DBusMessage *reply;
DBusMessageIter iter;
@@ -122,10 +140,22 @@ handle_start(DBusConnection *con, DBusMessage *msg)
GPid pid __attribute__ ((aligned));
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)) {
reply = dbus_message_new_method_return(msg);
@@ -183,7 +213,10 @@ 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);
diff --git a/hald-runner/runner.c b/hald-runner/runner.c
index 57a2a80..6a9676a 100644
--- a/hald-runner/runner.c
+++ b/hald-runner/runner.c
@@ -4,6 +4,7 @@
* runner.c - Process running code
*
* Copyright (C) 2006 Sjoerd Simons, <sjoerd at luon.net>
+ * Copyright (C) 2007 Codethink Ltd. Author Rob Taylor <rob.taylor at 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;
@@ -300,12 +302,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) {
@@ -363,6 +369,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/hald-runner/runner.h b/hald-runner/runner.h
index 2a18f94..c053381 100644
--- a/hald-runner/runner.h
+++ b/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;
diff --git a/hald/hald_runner.c b/hald/hald_runner.c
index 8fd5884..db708e4 100644
--- a/hald/hald_runner.c
+++ b/hald/hald_runner.c
@@ -4,6 +4,7 @@
* hald_runner.c - Interface to the hal runner helper daemon
*
* Copyright (C) 2006 Sjoerd Simons, <sjoerd at luon.net>
+ * Copyright (C) 2007 Codethink Ltd. Author Rob Taylor <rob.taylor at codethink.co.uk>
*
* Licensed under the Academic Free License version 2.1
*
@@ -65,6 +66,7 @@ typedef struct {
GPid pid;
HalDevice *device;
HalRunTerminatedCB cb;
+ gboolean is_singleton;
gpointer data1;
gpointer data2;
} RunningProcess;
@@ -366,7 +368,8 @@ add_basic_env (DBusMessageIter * iter, const gchar * udi)
if (hald_use_syslog) {
add_env (iter, "HALD_USE_SYSLOG", "1");
}
- add_env (iter, "UDI", udi);
+ if (udi)
+ add_env (iter, "UDI", udi);
add_env (iter, "HALD_DIRECT_ADDR", hald_dbus_local_server_addr ());
/* I'm sure it would be easy to remove use of getenv(3) to add these variables... */
@@ -559,11 +562,9 @@ add_command (DBusMessageIter * iter, const gchar * command_line)
return TRUE;
}
-static gboolean
-add_first_part (DBusMessageIter * iter, HalDevice * device,
- const gchar * command_line, char **extra_env)
+static void
+add_udi (DBusMessageIter * iter, HalDevice * device)
{
- DBusMessageIter array_iter;
const char *udi;
if (device != NULL)
@@ -572,7 +573,13 @@ add_first_part (DBusMessageIter * iter, HalDevice * device,
udi = "";
dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &udi);
+}
+static gboolean
+add_environment (DBusMessageIter * iter, HalDevice * device,
+ const gchar * command_line, char **extra_env)
+{
+ DBusMessageIter array_iter;
dbus_message_iter_open_container (iter,
DBUS_TYPE_ARRAY,
DBUS_TYPE_STRING_AS_STRING,
@@ -580,7 +587,7 @@ add_first_part (DBusMessageIter * iter, HalDevice * device,
if (device != NULL)
hal_device_property_foreach (device, add_property_to_msg,
&array_iter);
- add_basic_env (&array_iter, udi);
+ add_basic_env (&array_iter, device ? hal_device_get_udi (device): NULL);
add_extra_env (&array_iter, extra_env);
dbus_message_iter_close_container (iter, &array_iter);
@@ -591,31 +598,37 @@ add_first_part (DBusMessageIter * iter, HalDevice * device,
}
/* Start a helper, returns true on a successfull start */
-gboolean
-hald_runner_start (HalDevice * device, const gchar * command_line,
- char **extra_env, HalRunTerminatedCB cb, gpointer data1,
- gpointer data2)
+static gboolean
+runner_start (HalDevice * device, const gchar * command_line,
+ char **extra_env, gboolean singleton,
+ HalRunTerminatedCB cb, gpointer data1, gpointer data2)
{
DBusMessage *msg, *reply;
- DBusError err;
+ DBusError error;
DBusMessageIter iter;
- dbus_error_init (&err);
+ dbus_error_init (&error);
msg = dbus_message_new_method_call ("org.freedesktop.HalRunner",
"/org/freedesktop/HalRunner",
"org.freedesktop.HalRunner",
- "Start");
+ singleton ? "StartSingleton" : "Start");
if (msg == NULL)
DIE (("No memory"));
dbus_message_iter_init_append (msg, &iter);
- if (!add_first_part (&iter, device, command_line, extra_env))
+ if (!singleton)
+ add_udi (&iter, device);
+
+ if (!add_environment (&iter, device, command_line, extra_env)) {
+ HAL_ERROR (("Error adding environment, device =%p, singleton=%d",
+ device, singleton));
goto error;
+ }
/* Wait for the reply, should be almost instantanious */
reply =
dbus_connection_send_with_reply_and_block (runner_connection,
- msg, -1, &err);
+ msg, -1, &error);
if (reply) {
gboolean ret =
(dbus_message_get_type (reply) ==
@@ -623,7 +636,7 @@ hald_runner_start (HalDevice * device, const gchar * command_line,
if (ret) {
dbus_int64_t pid_from_runner;
- if (dbus_message_get_args (reply, &err,
+ if (dbus_message_get_args (reply, &error,
DBUS_TYPE_INT64,
&pid_from_runner,
DBUS_TYPE_INVALID)) {
@@ -632,7 +645,11 @@ hald_runner_start (HalDevice * device, const gchar * command_line,
rp = g_new0 (RunningProcess, 1);
rp->pid = (GPid) pid_from_runner;
rp->cb = cb;
- rp->device = device;
+ rp->is_singleton = singleton;
+ if (singleton)
+ rp->device = NULL;
+ else
+ rp->device = device;
rp->data1 = data1;
rp->data2 = data2;
@@ -649,6 +666,10 @@ hald_runner_start (HalDevice * device, const gchar * command_line,
dbus_message_unref (reply);
dbus_message_unref (msg);
return ret;
+ } else {
+ if (dbus_error_is_set (&error)) {
+ HAL_ERROR (("Error running '%s': %s: %s", command_line, error.name, error.message));
+ }
}
error:
@@ -656,6 +677,23 @@ hald_runner_start (HalDevice * device, const gchar * command_line,
return FALSE;
}
+gboolean
+hald_runner_start (HalDevice * device, const gchar * command_line,
+ char **extra_env, HalRunTerminatedCB cb,
+ gpointer data1, gpointer data2)
+{
+ return runner_start (device, command_line, extra_env, FALSE, cb, data1, data2);
+}
+
+gboolean
+hald_runner_start_singleton (const gchar * command_line,
+ char **extra_env, HalRunTerminatedCB cb,
+ gpointer data1, gpointer data2)
+{
+ return runner_start (NULL, command_line, extra_env, TRUE, cb, data1, data2);
+}
+
+
static void
process_reply (DBusMessage *m, HelperData *hb)
{
@@ -759,7 +797,8 @@ hald_runner_run_method (HalDevice * device,
DIE (("No memory"));
dbus_message_iter_init_append (msg, &iter);
- if (!add_first_part (&iter, device, command_line, extra_env))
+ add_udi (&iter, device);
+ if (!add_environment (&iter, device, command_line, extra_env))
goto error;
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &input);
@@ -828,7 +867,8 @@ hald_runner_run_sync (HalDevice * device,
DIE (("No memory"));
dbus_message_iter_init_append (msg, &iter);
- if (!add_first_part (&iter, device, command_line, extra_env))
+ add_udi (&iter, device);
+ if (!add_environment (&iter, device, command_line, extra_env))
goto error;
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &input);
diff --git a/hald/hald_runner.h b/hald/hald_runner.h
index c89eeee..44df683 100644
--- a/hald/hald_runner.h
+++ b/hald/hald_runner.h
@@ -5,6 +5,7 @@
* hald_runner.h - Interface to the hal runner helper daemon
*
* Copyright (C) 2006 Sjoerd Simons <sjoerd at luon.net>
+ * Copyright (C) 2007 Codethink Ltd. Author Rob Taylor <rob.taylor at codethink.co.uk>
*
* Licensed under the Academic Free License version 2.1
*
@@ -61,6 +62,11 @@ gboolean
hald_runner_start (HalDevice *device, const gchar *command_line, char **extra_env,
HalRunTerminatedCB cb, gpointer data1, gpointer data2);
+gboolean
+hald_runner_start_singleton (const gchar * command_line,
+ char **extra_env, HalRunTerminatedCB cb,
+ gpointer data1, gpointer data2);
+
/* Run a helper program using the commandline, with input as infomation on
* stdin */
void
@@ -94,4 +100,5 @@ void runner_device_finalized (HalDevice *device);
typedef void (*HaldRunnerRunNotify)(gpointer user_data);
void hald_runner_set_method_run_notify (HaldRunnerRunNotify cb, gpointer user_data);
+void hald_add_device_info (DBusMessageIter * iter, HalDevice * device, char **extra_env);
#endif
--
1.5.2-rc3.GIT
--------------050607030001010405020902
Content-Type: text/x-patch;
name="0002-hald-core-support-for-singleton-addons.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="0002-hald-core-support-for-singleton-addons.patch"
More information about the hal
mailing list