summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2006-09-10 17:28:34 -0400
committerDavid Zeuthen <davidz@redhat.com>2006-09-10 17:28:34 -0400
commit18413734b1da6c14a0851e34d77db96f6a4ef9bb (patch)
tree930395c667e5518610ab6c22c4970835830317af
parented71e4e6769b8f359f7626f788a38db5f63faca8 (diff)
require addons to call libhal_device_addon_is_ready() to make device visible
Also fixup some .gitignore files and prune the TODO for finished items.
-rw-r--r--doc/TODO6
-rw-r--r--doc/api/tmpl/device.sgml2
-rw-r--r--doc/api/tmpl/hald_runner.sgml3
-rw-r--r--doc/api/tmpl/runner.sgml1
-rw-r--r--hald-runner/main.c9
-rw-r--r--hald-runner/runner.c28
-rw-r--r--hald-runner/runner.h2
-rw-r--r--hald/device.c34
-rw-r--r--hald/device.h10
-rw-r--r--hald/hald.c60
-rw-r--r--hald/hald_dbus.c74
-rw-r--r--hald/hald_runner.c152
-rw-r--r--hald/hald_runner.h12
-rw-r--r--hald/linux/addons/addon-acpi-buttons-toshiba.c5
-rw-r--r--hald/linux/addons/addon-acpi.c6
-rw-r--r--hald/linux/addons/addon-cpufreq.c6
-rw-r--r--hald/linux/addons/addon-hid-ups.c8
-rw-r--r--hald/linux/addons/addon-keyboard.c6
-rw-r--r--hald/linux/addons/addon-macbookpro-backlight.c6
-rw-r--r--hald/linux/addons/addon-pmu.c6
-rw-r--r--hald/linux/addons/addon-storage.c5
-rw-r--r--hald/linux/addons/addon-usb-csr.c6
-rw-r--r--libhal/libhal.c64
-rw-r--r--libhal/libhal.h3
-rw-r--r--partutil/.gitignore8
-rw-r--r--tools/.gitignore1
26 files changed, 482 insertions, 41 deletions
diff --git a/doc/TODO b/doc/TODO
index b7939f61..4ad533e1 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -15,12 +15,6 @@ Ongoing items that always need work
Items specifically planned for 0.5.8
------------------------------------
- - Provide a libhal_device_set_all_properties plus functions to construct
- a LibHalPropertySet
-
- - Require that addons poke hald before the device is visible - this is for
- addons that also probes the hardware and provide the initial state..
-
- Move /usr/libexec to /usr/lib/hal/ - drop /usr/lib/hal/scripts -
use /usr/lib/hal/methods
diff --git a/doc/api/tmpl/device.sgml b/doc/api/tmpl/device.sgml
index 5ff559eb..d5a02b64 100644
--- a/doc/api/tmpl/device.sgml
+++ b/doc/api/tmpl/device.sgml
@@ -25,6 +25,8 @@ HalDevice
@parent:
@udi:
@properties:
+@num_addons:
+@num_addons_ready:
<!-- ##### USER_FUNCTION HalDeviceAsyncCallback ##### -->
<para>
diff --git a/doc/api/tmpl/hald_runner.sgml b/doc/api/tmpl/hald_runner.sgml
index 70ff5ff8..9537d0a0 100644
--- a/doc/api/tmpl/hald_runner.sgml
+++ b/doc/api/tmpl/hald_runner.sgml
@@ -81,6 +81,9 @@ hald_runner
@device:
@command_line:
@extra_env:
+@cb:
+@data1:
+@data2:
@Returns:
diff --git a/doc/api/tmpl/runner.sgml b/doc/api/tmpl/runner.sgml
index 78d1be66..3bdfba69 100644
--- a/doc/api/tmpl/runner.sgml
+++ b/doc/api/tmpl/runner.sgml
@@ -60,6 +60,7 @@ runner
@r:
@con:
@msg:
+@out_pid:
@Returns:
diff --git a/hald-runner/main.c b/hald-runner/main.c
index 6d399816..fbb7a633 100644
--- a/hald-runner/main.c
+++ b/hald-runner/main.c
@@ -94,7 +94,7 @@ handle_run(DBusConnection *con, DBusMessage *msg)
dbus_message_iter_get_basic(&iter, &(r->timeout));
/* let run_request_run handle the reply */
- run_request_run(r, con, msg);
+ run_request_run(r, con, msg, NULL);
return;
malformed:
@@ -111,6 +111,7 @@ handle_start(DBusConnection *con, DBusMessage *msg)
DBusMessage *reply;
DBusMessageIter iter;
run_request *r;
+ GPid pid;
r = new_run_request();
g_assert(dbus_message_iter_init(msg, &iter));
@@ -118,8 +119,12 @@ handle_start(DBusConnection *con, DBusMessage *msg)
if (!dbus_message_iter_init(msg, &iter) || !parse_first_part(r, msg, &iter))
goto malformed;
- if (run_request_run(r, NULL, NULL)) {
+ if (run_request_run(r, con, NULL, &pid)) {
reply = dbus_message_new_method_return(msg);
+ dbus_message_append_args (reply,
+ DBUS_TYPE_INT64, &pid,
+ DBUS_TYPE_INVALID);
+
} else {
reply = dbus_message_new_error(msg, "org.freedesktop.HalRunner.Failed",
"Start request failed");
diff --git a/hald-runner/runner.c b/hald-runner/runner.c
index 73012338..3fb1fb25 100644
--- a/hald-runner/runner.c
+++ b/hald-runner/runner.c
@@ -58,6 +58,7 @@ typedef struct {
guint watch;
guint timeout;
gboolean sent_kill;
+ gboolean emit_pid_exited;
} run_data;
static void
@@ -155,9 +156,7 @@ run_exited(GPid pid, gint status, gpointer data)
if (!WIFEXITED(status)) {
/* No not normal termination ? crash ? */
send_reply(rd->con, rd->msg, HALD_RUN_FAILED, 0, NULL);
- remove_from_hash_table(rd);
- del_run_data(rd);
- return;
+ goto out;
}
/* normal exit */
if (rd->stderr_v >= 0) {
@@ -169,7 +168,22 @@ run_exited(GPid pid, gint status, gpointer data)
if (rd->msg != NULL)
send_reply(rd->con, rd->msg, HALD_RUN_SUCCESS, WEXITSTATUS(status), error);
free_string_array(error);
+
+out:
remove_from_hash_table(rd);
+
+ /* emit a signal that this PID exited */
+ if(rd->con != NULL && rd->emit_pid_exited) {
+ DBusMessage *signal;
+ signal = dbus_message_new_signal ("/org/freedesktop/HalRunner",
+ "org.freedesktop.HalRunner",
+ "StartedProcessExited");
+ dbus_message_append_args (signal,
+ DBUS_TYPE_INT64, &(rd->pid),
+ DBUS_TYPE_INVALID);
+ dbus_connection_send(rd->con, signal, NULL);
+ }
+
del_run_data(rd);
}
@@ -217,7 +231,7 @@ find_program(char **argv)
/* Run the given request and reply it's result on msg */
gboolean
-run_request_run(run_request *r, DBusConnection *con, DBusMessage *msg)
+run_request_run (run_request *r, DBusConnection *con, DBusMessage *msg, GPid *out_pid)
{
GPid pid;
GError *error = NULL;
@@ -292,6 +306,12 @@ run_request_run(run_request *r, DBusConnection *con, DBusMessage *msg)
/* 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) {
+ *out_pid = pid;
+ rd->emit_pid_exited = TRUE;
+ }
return TRUE;
}
diff --git a/hald-runner/runner.h b/hald-runner/runner.h
index f15fd336..2a18f941 100644
--- a/hald-runner/runner.h
+++ b/hald-runner/runner.h
@@ -43,7 +43,7 @@ run_request *new_run_request(void);
void del_run_request(run_request *r);
/* Run the given request and reply it's result on msg */
-gboolean run_request_run(run_request *r, DBusConnection *con, DBusMessage *msg);
+gboolean run_request_run(run_request *r, DBusConnection *con, DBusMessage *msg, GPid *out_pid);
/* Kill all running request for a udi */
void run_kill_udi(gchar *udi);
diff --git a/hald/device.c b/hald/device.c
index ea7cf082..f54401f7 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -35,6 +35,7 @@
#include "device.h"
#include "hald_marshal.h"
#include "logger.h"
+#include "hald_runner.h"
static GObjectClass *parent_class;
@@ -57,11 +58,14 @@ hal_device_finalize (GObject *obj)
{
HalDevice *device = HAL_DEVICE (obj);
+ runner_device_finalized (device);
+
#ifdef HALD_MEMLEAK_DBG
dbg_hal_device_object_delta--;
printf ("************* in finalize for udi=%s\n", device->udi);
#endif
+
g_slist_foreach (device->properties, (GFunc) hal_property_free, NULL);
g_free (device->udi);
@@ -132,6 +136,8 @@ hal_device_init (HalDevice *device)
device->udi = g_strdup_printf ("/org/freedesktop/Hal/devices/temp/%d",
temp_device_counter++);
+ device->num_addons = 0;
+ device->num_addons_ready = 0;
}
GType
@@ -1314,3 +1320,31 @@ hal_device_property_strlist_is_empty (HalDevice *device,
return FALSE;
}
+void
+hal_device_inc_num_addons (HalDevice *device)
+{
+ device->num_addons++;
+}
+
+gboolean
+hal_device_inc_num_ready_addons (HalDevice *device)
+{
+ if (hal_device_are_all_addons_ready (device)) {
+ HAL_ERROR (("In hal_device_inc_num_ready_addons for udi=%s but all addons are already ready!",
+ device->udi));
+ return FALSE;
+ }
+
+ device->num_addons_ready++;
+ return TRUE;
+}
+
+gboolean
+hal_device_are_all_addons_ready (HalDevice *device)
+{
+ if (device->num_addons_ready == device->num_addons) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
diff --git a/hald/device.h b/hald/device.h
index c31353f6..a9531baf 100644
--- a/hald/device.h
+++ b/hald/device.h
@@ -41,6 +41,9 @@ struct _HalDevice {
char *udi;
GSList *properties;
+
+ int num_addons;
+ int num_addons_ready;
};
struct _HalDeviceClass {
@@ -202,4 +205,11 @@ gboolean hal_device_property_set_attribute (HalDevice *device,
enum PropertyAttribute attr,
gboolean persistence);
+void hal_device_inc_num_addons (HalDevice *device);
+
+gboolean hal_device_inc_num_ready_addons (HalDevice *device);
+
+gboolean hal_device_are_all_addons_ready (HalDevice *device);
+
+
#endif /* DEVICE_H */
diff --git a/hald/hald.c b/hald/hald.c
index f10c087d..02ae7a09 100644
--- a/hald/hald.c
+++ b/hald/hald.c
@@ -73,6 +73,29 @@ static HalDeviceStore *global_device_list = NULL;
static HalDeviceStore *temporary_device_list = NULL;
+
+static void
+addon_terminated (HalDevice *device, guint32 exit_type,
+ gint return_code, gchar **error,
+ gpointer data1, gpointer data2)
+{
+ HAL_INFO (("in addon_terminated for udi=%s", device->udi));
+
+ /* TODO: log to syslog - addons shouldn't just terminate, this is a bug with the addon */
+
+ /* however, the world can stop, mark this addon as ready
+ * (TODO: potential bug if the addon crashed after calling libhal_device_addon_is_ready())
+ */
+ if (hal_device_inc_num_ready_addons (device)) {
+ if (hal_device_are_all_addons_ready (device)) {
+ manager_send_signal_device_added (device);
+ }
+ }
+}
+
+
+
+
static void
gdl_store_changed (HalDeviceStore *store, HalDevice *device,
gboolean is_added, gpointer user_data)
@@ -84,29 +107,38 @@ gdl_store_changed (HalDeviceStore *store, HalDevice *device,
if ((addons = hal_device_property_get_strlist (device, "info.addons")) != NULL) {
GSList *i;
-
+
for (i = addons; i != NULL; i = g_slist_next (i)) {
const gchar *command_line;
gchar *extra_env[2] = {"HALD_ACTION=addon", NULL};
command_line = (const gchar *) i->data;
- hald_runner_start (device, command_line, extra_env);
-
- HAL_INFO (("Started addon %s for udi %s",
- command_line, hal_device_get_udi(device)));
+ if (hald_runner_start(device, command_line, extra_env, addon_terminated, NULL, NULL)) {
+ HAL_INFO (("Started addon %s for udi %s",
+ command_line, hal_device_get_udi(device)));
+ hal_device_inc_num_addons (device);
+ } else {
+ HAL_ERROR (("Cannot start addon %s for udi %s",
+ command_line, hal_device_get_udi(device)));
+ }
}
}
} else {
HAL_INFO (("Removed device from GDL; udi=%s", hal_device_get_udi(device)));
- hald_runner_kill_device(device);
+ hald_runner_kill_device(device);
}
/*hal_device_print (device);*/
- if (is_added)
- manager_send_signal_device_added (device);
- else
- manager_send_signal_device_removed (device);
+ if (is_added) {
+ if (hal_device_are_all_addons_ready (device)) {
+ manager_send_signal_device_added (device);
+ }
+ } else {
+ if (hal_device_are_all_addons_ready (device)) {
+ manager_send_signal_device_removed (device);
+ }
+ }
}
static void
@@ -114,7 +146,9 @@ gdl_property_changed (HalDeviceStore *store, HalDevice *device,
const char *key, gboolean added, gboolean removed,
gpointer user_data)
{
- device_send_signal_property_modified (device, key, removed, added);
+ if (hal_device_are_all_addons_ready (device)) {
+ device_send_signal_property_modified (device, key, removed, added);
+ }
/* only execute the callouts if the property _changed_ */
if (added == FALSE && removed == FALSE)
@@ -125,7 +159,9 @@ static void
gdl_capability_added (HalDeviceStore *store, HalDevice *device,
const char *capability, gpointer user_data)
{
- manager_send_signal_new_capability (device, capability);
+ if (hal_device_are_all_addons_ready (device)) {
+ manager_send_signal_new_capability (device, capability);
+ }
/*hal_callout_capability (device, capability, TRUE)*/;
}
diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index 3e270af7..a367f728 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -2505,6 +2505,70 @@ device_claim_interface (DBusConnection * connection, DBusMessage * message, dbus
}
+
+static DBusHandlerResult
+addon_is_ready (DBusConnection * connection, DBusMessage * message, dbus_bool_t local_interface)
+{
+ const char *udi;
+ HalDevice *device;
+ DBusMessageIter iter;
+ DBusMessage *reply;
+ DBusError error;
+ const char *interface_name;
+ const char *introspection_xml;
+ dbus_bool_t res;
+
+ HAL_TRACE (("entering"));
+
+ udi = dbus_message_get_path (message);
+
+ if (!local_interface) {
+ raise_permission_denied (connection, message, "AddonIsReady: only allowed for helpers");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ HAL_DEBUG (("udi=%s", udi));
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "AddonIsReady");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ device = hal_device_store_find (hald_get_gdl (), udi);
+ if (device == NULL)
+ device = hal_device_store_find (hald_get_tdl (), udi);
+
+ if (device == NULL) {
+ raise_no_such_device (connection, message, udi);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ if (hal_device_inc_num_ready_addons (device)) {
+ if (hal_device_are_all_addons_ready (device)) {
+ manager_send_signal_device_added (device);
+ }
+ }
+
+ res = TRUE;
+
+ HAL_INFO (("AddonIsReady on udi '%s'", udi));
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ DIE (("No memory"));
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &res);
+
+ if (!dbus_connection_send (connection, reply, NULL))
+ DIE (("No memory"));
+
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+
/*
* Create new device in tdl. Return temporary udi.
*/
@@ -3331,6 +3395,7 @@ do_introspect (DBusConnection *connection,
" <method name=\"EmitCondition\">\n"
" <arg name=\"condition_name\" direction=\"in\" type=\"s\"/>\n"
" <arg name=\"condition_details\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"rc\" direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" <method name=\"Rescan\">\n"
@@ -3343,6 +3408,11 @@ do_introspect (DBusConnection *connection,
" <method name=\"ClaimInterface\">\n"
" <arg name=\"interface_name\" direction=\"in\" type=\"s\"/>\n"
" <arg name=\"introspection_xml\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"rc\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
+
+ " <method name=\"AddonIsReady\">\n"
+ " <arg name=\"rc\" direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" </interface>\n");
@@ -3666,6 +3736,10 @@ hald_dbus_filter_handle_methods (DBusConnection *connection, DBusMessage *messag
return device_release_interface (connection, message, local_interface);
#endif
} else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device",
+ "AddonIsReady")) {
+ return addon_is_ready (connection, message, local_interface);
+ } else if (dbus_message_is_method_call (message,
"org.freedesktop.DBus.Introspectable",
"Introspect")) {
return do_introspect (connection, message, local_interface);
diff --git a/hald/hald_runner.c b/hald/hald_runner.c
index 6a259ffb..4fa7b440 100644
--- a/hald/hald_runner.c
+++ b/hald/hald_runner.c
@@ -51,17 +51,117 @@ typedef struct {
static DBusConnection *runner_connection = NULL;
+typedef struct
+{
+ GPid pid;
+ HalDevice *device;
+ HalRunTerminatedCB cb;
+ gpointer data1;
+ gpointer data2;
+} RunningProcess;
+
+/* mapping from PID to RunningProcess */
+static GHashTable *running_processes;
+
+static gboolean
+rprd_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ gboolean remove;
+ RunningProcess *rp = value;
+ HalDevice *device = user_data;
+
+ if (rp->device == device) {
+ remove = TRUE;
+ g_free (rp);
+ }
+
+ return remove;
+}
+
+static void
+running_processes_remove_device (HalDevice *device)
+{
+ g_hash_table_foreach_remove (running_processes, rprd_foreach, device);
+}
+
+void
+runner_device_finalized (HalDevice *device)
+{
+ running_processes_remove_device (device);
+}
+
+
+static DBusHandlerResult
+runner_server_message_handler (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+
+ /*HAL_INFO (("runner_server_message_handler: destination=%s obj_path=%s interface=%s method=%s",
+ dbus_message_get_destination (message),
+ dbus_message_get_path (message),
+ dbus_message_get_interface (message),
+ dbus_message_get_member (message)));*/
+
+ if (dbus_message_is_signal (message,
+ "org.freedesktop.HalRunner",
+ "StartedProcessExited")) {
+ GPid pid;
+ DBusError error;
+ dbus_error_init (&error);
+ if (dbus_message_get_args (message, &error,
+ DBUS_TYPE_INT64, &pid,
+ DBUS_TYPE_INVALID)) {
+ RunningProcess *rp;
+
+ /*HAL_INFO (("Previously started process with pid %d exited", pid));*/
+
+ rp = g_hash_table_lookup (running_processes, (gpointer) pid);
+ if (rp != NULL) {
+ rp->cb (rp->device, 0, 0, NULL, rp->data1, rp->data2);
+ g_hash_table_remove (running_processes, (gpointer) pid);
+ g_free (rp);
+ }
+ }
+
+ }
+
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void
+runner_server_unregister_handler (DBusConnection *connection, void *user_data)
+{
+ HAL_INFO (("unregistered"));
+}
+
+
static void
handle_connection(DBusServer *server,
DBusConnection *new_connection,
- void *data) {
+ void *data)
+{
- if (runner_connection == NULL) {
- runner_connection = new_connection;
- dbus_connection_ref (new_connection);
- dbus_connection_setup_with_g_main (new_connection, NULL);
- /* dbus_server_unref(server); */
- }
+ if (runner_connection == NULL) {
+ DBusObjectPathVTable vtable = { &runner_server_unregister_handler,
+ &runner_server_message_handler,
+ NULL, NULL, NULL, NULL};
+
+ runner_connection = new_connection;
+ dbus_connection_ref (new_connection);
+ dbus_connection_setup_with_g_main (new_connection, NULL);
+
+ dbus_connection_register_fallback (new_connection,
+ "/org/freedesktop",
+ &vtable,
+ NULL);
+
+ /* dbus_server_unref(server); */
+
+ }
}
static void
@@ -81,6 +181,8 @@ hald_runner_start_runner(void)
char *env[] = { NULL, NULL, NULL, NULL};
const char *hald_runner_path;
+ running_processes = g_hash_table_new (g_direct_hash, g_direct_equal);
+
dbus_error_init(&err);
server = dbus_server_listen(DBUS_SERVER_ADDRESS, &err);
if (server == NULL) {
@@ -91,6 +193,8 @@ hald_runner_start_runner(void)
dbus_server_setup_with_g_main(server, NULL);
dbus_server_set_new_connection_function(server, handle_connection,
NULL, NULL);
+
+
argv[0] = "hald-runner";
env[0] = g_strdup_printf("HALD_RUNNER_DBUS_ADDRESS=%s",
dbus_server_get_address(server));
@@ -255,8 +359,9 @@ 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) {
+hald_runner_start (HalDevice *device, const gchar *command_line, char **extra_env,
+ HalRunTerminatedCB cb, gpointer data1, gpointer data2)
+{
DBusMessage *msg, *reply;
DBusError err;
DBusMessageIter iter;
@@ -280,6 +385,28 @@ hald_runner_start(HalDevice *device,
if (reply) {
gboolean ret =
(dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN);
+
+ if (ret) {
+ dbus_int64_t pid_from_runner;
+ if (dbus_message_get_args (reply, &err,
+ DBUS_TYPE_INT64, &pid_from_runner,
+ DBUS_TYPE_INVALID)) {
+ if (cb != NULL) {
+ RunningProcess *rp;
+ rp = g_new0 (RunningProcess, 1);
+ rp->pid = (GPid) pid_from_runner;
+ rp->cb = cb;
+ rp->device = device;
+ rp->data1 = data1;
+ rp->data2 = data2;
+
+ g_hash_table_insert (running_processes, (gpointer) rp->pid, rp);
+ }
+ } else {
+ HAL_ERROR (("Error extracting out_pid from runner's Start()"));
+ }
+ }
+
dbus_message_unref(reply);
dbus_message_unref(msg);
return ret;
@@ -402,12 +529,16 @@ hald_runner_run(HalDevice *device,
"", FALSE, timeout, cb, data1, data2);
}
+
+
void
hald_runner_kill_device(HalDevice *device) {
DBusMessage *msg, *reply;
DBusError err;
DBusMessageIter iter;
const char *udi;
+
+ running_processes_remove_device (device);
msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
"/org/freedesktop/HalRunner",
@@ -434,6 +565,9 @@ void
hald_runner_kill_all(HalDevice *device) {
DBusMessage *msg, *reply;
DBusError err;
+
+ running_processes_remove_device (device);
+
msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
"/org/freedesktop/HalRunner",
"org.freedesktop.HalRunner",
diff --git a/hald/hald_runner.h b/hald/hald_runner.h
index a098ec45..ca055733 100644
--- a/hald/hald_runner.h
+++ b/hald/hald_runner.h
@@ -49,10 +49,13 @@ typedef void (*HalRunTerminatedCB) (HalDevice *d, guint32 exit_type,
gboolean
hald_runner_start_runner(void);
-/* Start a helper, returns true on a successfull start */
+/* Start a helper, returns true on a successfull start.
+ * cb will be called on abnormal or premature termination
+ * only
+ */
gboolean
-hald_runner_start(HalDevice *device, const gchar *command_line,
- char **extra_env);
+hald_runner_start (HalDevice *device, 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 */
@@ -73,4 +76,7 @@ hald_runner_run_method(HalDevice *device,
void hald_runner_kill_device(HalDevice *device);
void hald_runner_kill_all();
+/* called by the core to tell the runner a device was finalized */
+void runner_device_finalized (HalDevice *device);
+
#endif
diff --git a/hald/linux/addons/addon-acpi-buttons-toshiba.c b/hald/linux/addons/addon-acpi-buttons-toshiba.c
index 7252759e..eb833efa 100644
--- a/hald/linux/addons/addon-acpi-buttons-toshiba.c
+++ b/hald/linux/addons/addon-acpi-buttons-toshiba.c
@@ -164,6 +164,11 @@ main (int argc, char **argv)
return 1;
}
+ dbus_error_init (&error);
+ if (!libhal_device_addon_is_ready (ctx, udi, &error)) {
+ return 1;
+ }
+
/* Check for Toshiba ACPI interface /proc/acpi/toshiba/keys */
fp = fopen (TOSHIBA_ACPI_KEYS, "r+");
if (!fp) {
diff --git a/hald/linux/addons/addon-acpi.c b/hald/linux/addons/addon-acpi.c
index 4b193212..ac84a9e9 100644
--- a/hald/linux/addons/addon-acpi.c
+++ b/hald/linux/addons/addon-acpi.c
@@ -170,12 +170,16 @@ main (int argc, char **argv)
setup_logger ();
dbus_error_init (&error);
-
if ((ctx = libhal_ctx_init_direct (&error)) == NULL) {
HAL_ERROR (("Unable to initialise libhal context: %s", error.message));
return 1;
}
+ dbus_error_init (&error);
+ if (!libhal_device_addon_is_ready (ctx, getenv ("UDI"), &error)) {
+ return 1;
+ }
+
#ifdef ACPI_PROC
/* If we can connect directly to the kernel then do so. */
eventfp = acpi_get_event_fp_kernel ();
diff --git a/hald/linux/addons/addon-cpufreq.c b/hald/linux/addons/addon-cpufreq.c
index 92d1767b..fbc30ef3 100644
--- a/hald/linux/addons/addon-cpufreq.c
+++ b/hald/linux/addons/addon-cpufreq.c
@@ -1090,6 +1090,12 @@ gboolean dbus_init(void)
goto Error;
}
+ dbus_error_init (&dbus_error);
+ if (!libhal_device_addon_is_ready (halctx, udi, &dbus_error)) {
+ goto Error;
+ }
+
+
if (!libhal_device_claim_interface(halctx, udi,
"org.freedesktop.Hal.Device.CPUFreq",
" <method name=\"SetCPUFreqGovernor\">\n"
diff --git a/hald/linux/addons/addon-hid-ups.c b/hald/linux/addons/addon-hid-ups.c
index c073eb75..698d8939 100644
--- a/hald/linux/addons/addon-hid-ups.c
+++ b/hald/linux/addons/addon-hid-ups.c
@@ -142,7 +142,6 @@ ups_get_static (LibHalContext *ctx, const char *udi, int fd,
goto out;
}
-
/* set to failure */
ret = FALSE;
@@ -326,9 +325,13 @@ main (int argc, char *argv[])
if (!ups_get_static (ctx, udi, fd, &prop_remaining, &prop_runtime, &prop_charging, &prop_discharging))
goto out;
-
hal_set_proc_title ("hald-addon-hid-ups: listening on %s", device_file);
+ dbus_error_init (&error);
+ if (!libhal_device_addon_is_ready (ctx, udi, &error)) {
+ goto out;
+ }
+
FD_ZERO(&fdset);
while (1) {
FD_SET(fd, &fdset);
@@ -336,7 +339,6 @@ main (int argc, char *argv[])
if (rd > 0) {
- DBusError error;
LibHalChangeSet *cs;
rd = read(fd, ev, sizeof(ev));
diff --git a/hald/linux/addons/addon-keyboard.c b/hald/linux/addons/addon-keyboard.c
index a054ac97..13f4fd55 100644
--- a/hald/linux/addons/addon-keyboard.c
+++ b/hald/linux/addons/addon-keyboard.c
@@ -200,6 +200,12 @@ main (int argc, char **argv)
if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
goto out;
+ dbus_error_init (&error);
+ if (!libhal_device_addon_is_ready (ctx, udi, &error)) {
+ goto out;
+ }
+
+
eventfp = fopen(device_file, "r");
if (!eventfp)
diff --git a/hald/linux/addons/addon-macbookpro-backlight.c b/hald/linux/addons/addon-macbookpro-backlight.c
index f25a555a..53dbb90d 100644
--- a/hald/linux/addons/addon-macbookpro-backlight.c
+++ b/hald/linux/addons/addon-macbookpro-backlight.c
@@ -422,6 +422,12 @@ main (int argc, char *argv[])
return -3;
}
+ dbus_error_init (&err);
+ if (!libhal_device_addon_is_ready (halctx, udi, &err)) {
+ return -4;
+ }
+
+
conn = libhal_ctx_get_dbus_connection (halctx);
dbus_connection_setup_with_g_main (conn, NULL);
diff --git a/hald/linux/addons/addon-pmu.c b/hald/linux/addons/addon-pmu.c
index 68b59fe9..f2924600 100644
--- a/hald/linux/addons/addon-pmu.c
+++ b/hald/linux/addons/addon-pmu.c
@@ -66,6 +66,12 @@ main (int argc, char *argv[])
if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
goto out;
+ dbus_error_init (&error);
+ if (!libhal_device_addon_is_ready (ctx, udi, &error)) {
+ goto out;
+ }
+
+
/* initial state */
if ((strstate = getenv ("HAL_PROP_BUTTON_STATE_VALUE")) == NULL) {
HAL_ERROR (("Cannot get HAL_PROP_BUTTON_STATE_VALUE"));
diff --git a/hald/linux/addons/addon-storage.c b/hald/linux/addons/addon-storage.c
index 5d848c54..22247cfc 100644
--- a/hald/linux/addons/addon-storage.c
+++ b/hald/linux/addons/addon-storage.c
@@ -302,6 +302,11 @@ main (int argc, char *argv[])
if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
goto out;
+ dbus_error_init (&error);
+ if (!libhal_device_addon_is_ready (ctx, udi, &error)) {
+ goto out;
+ }
+
HAL_DEBUG (("**************************************************"));
HAL_DEBUG (("Doing addon-storage for %s (bus %s) (drive_type %s) (udi %s)", device_file, bus, drive_type, udi));
HAL_DEBUG (("**************************************************"));
diff --git a/hald/linux/addons/addon-usb-csr.c b/hald/linux/addons/addon-usb-csr.c
index cd1747dc..a761108f 100644
--- a/hald/linux/addons/addon-usb-csr.c
+++ b/hald/linux/addons/addon-usb-csr.c
@@ -281,6 +281,7 @@ main (int argc, char *argv[])
return -3;
}
+
/* update_properties */
dbus_error_init (&err);
libhal_device_set_property_bool (halctx, device_udi,
@@ -315,6 +316,11 @@ main (int argc, char *argv[])
dbus_error_init (&err);
libhal_device_add_capability (halctx, device_udi, "battery", &err);
+ dbus_error_init (&err);
+ if (!libhal_device_addon_is_ready (halctx, device_udi, &err)) {
+ return -4;
+ }
+
hal_set_proc_title ("hald-addon-usb-csr: listening on '%s'",
libhal_device_get_property_string(halctx, device_udi,
"info.product", &err));
diff --git a/libhal/libhal.c b/libhal/libhal.c
index 0627aaad..a577829c 100644
--- a/libhal/libhal.c
+++ b/libhal/libhal.c
@@ -3379,6 +3379,70 @@ dbus_bool_t libhal_device_emit_condition (LibHalContext *ctx,
}
/**
+ * libhal_device_addon_is_ready:
+ * @ctx: the context for the connection to hald
+ * @udi: the Unique Device Id
+ * @error: pointer to an initialized dbus error object for returning errors or NULL
+ *
+ * HAL addon's must call this method when they are done initializing the device object. The HAL
+ * daemon will wait for all addon's to call this.
+ *
+ * Can only be used from hald helpers.
+ *
+ * Returns: TRUE if the HAL daemon received the message, FALSE otherwise
+ */
+dbus_bool_t
+libhal_device_addon_is_ready (LibHalContext *ctx, const char *udi, DBusError *error)
+{
+ DBusMessage *message;
+ DBusMessageIter iter;
+ DBusMessageIter reply_iter;
+ DBusMessage *reply;
+ dbus_bool_t result;
+
+ LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.Hal",
+ udi,
+ "org.freedesktop.Hal.Device",
+ "AddonIsReady");
+
+ if (message == NULL) {
+ fprintf (stderr,
+ "%s %d : Couldn't allocate D-BUS message\n",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ dbus_message_iter_init_append (message, &iter);
+
+ reply = dbus_connection_send_with_reply_and_block (ctx->connection,
+ message, -1,
+ error);
+
+ if (dbus_error_is_set (error)) {
+ dbus_message_unref (message);
+ return FALSE;
+ }
+
+ dbus_message_unref (message);
+
+ if (reply == NULL)
+ return FALSE;
+
+ dbus_message_iter_init (reply, &reply_iter);
+ if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ return FALSE;
+ }
+ dbus_message_iter_get_basic (&reply_iter, &result);
+
+ dbus_message_unref (reply);
+ return result;
+}
+
+/**
* libhal_device_claim_interface:
* @ctx: the context for the connection to hald
* @udi: the Unique Device Id
diff --git a/libhal/libhal.h b/libhal/libhal.h
index ab00e576..9962da1e 100644
--- a/libhal/libhal.h
+++ b/libhal/libhal.h
@@ -593,6 +593,9 @@ dbus_bool_t libhal_device_claim_interface (LibHalContext *ctx,
const char *introspection_xml,
DBusError *error);
+/* hald waits for all addons to call this function before announcing the addon (for hald helpers only) */
+dbus_bool_t libhal_device_addon_is_ready (LibHalContext *ctx, const char *udi, DBusError *error);
+
#if defined(__cplusplus)
}
diff --git a/partutil/.gitignore b/partutil/.gitignore
new file mode 100644
index 00000000..0ec65bf0
--- /dev/null
+++ b/partutil/.gitignore
@@ -0,0 +1,8 @@
+.deps
+.libs
+Makefile
+Makefile.in
+*.la
+*.lo
+*.o
+*~
diff --git a/tools/.gitignore b/tools/.gitignore
index 1df1a5cc..94316c81 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -19,5 +19,6 @@ hal-storage-cleanup-all-mountpoints
hal-storage-cleanup-mountpoint
hal-storage-eject
hal-storage-unmount
+hal-storage-closetray
*.o
*~