diff options
-rw-r--r-- | doc/TODO | 6 | ||||
-rw-r--r-- | doc/api/tmpl/device.sgml | 2 | ||||
-rw-r--r-- | doc/api/tmpl/hald_runner.sgml | 3 | ||||
-rw-r--r-- | doc/api/tmpl/runner.sgml | 1 | ||||
-rw-r--r-- | hald-runner/main.c | 9 | ||||
-rw-r--r-- | hald-runner/runner.c | 28 | ||||
-rw-r--r-- | hald-runner/runner.h | 2 | ||||
-rw-r--r-- | hald/device.c | 34 | ||||
-rw-r--r-- | hald/device.h | 10 | ||||
-rw-r--r-- | hald/hald.c | 60 | ||||
-rw-r--r-- | hald/hald_dbus.c | 74 | ||||
-rw-r--r-- | hald/hald_runner.c | 152 | ||||
-rw-r--r-- | hald/hald_runner.h | 12 | ||||
-rw-r--r-- | hald/linux/addons/addon-acpi-buttons-toshiba.c | 5 | ||||
-rw-r--r-- | hald/linux/addons/addon-acpi.c | 6 | ||||
-rw-r--r-- | hald/linux/addons/addon-cpufreq.c | 6 | ||||
-rw-r--r-- | hald/linux/addons/addon-hid-ups.c | 8 | ||||
-rw-r--r-- | hald/linux/addons/addon-keyboard.c | 6 | ||||
-rw-r--r-- | hald/linux/addons/addon-macbookpro-backlight.c | 6 | ||||
-rw-r--r-- | hald/linux/addons/addon-pmu.c | 6 | ||||
-rw-r--r-- | hald/linux/addons/addon-storage.c | 5 | ||||
-rw-r--r-- | hald/linux/addons/addon-usb-csr.c | 6 | ||||
-rw-r--r-- | libhal/libhal.c | 64 | ||||
-rw-r--r-- | libhal/libhal.h | 3 | ||||
-rw-r--r-- | partutil/.gitignore | 8 | ||||
-rw-r--r-- | tools/.gitignore | 1 |
26 files changed, 482 insertions, 41 deletions
@@ -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 *~ |