Merge authors: James Hunt (jamesodhunt) Related merge proposals: https://code.launchpad.net/~jamesodhunt/upstart/upstart-dbus-bridge/+merge/161772 proposed by: James Hunt (jamesodhunt) review: Approve - Dmitrijs Ledkovs (xnox) ------------------------------------------------------------ revno: 1486 [merge] committer: Dmitrijs Ledkovs <[email protected]> branch nick: upstart timestamp: Wed 2013-06-26 10:15:41 +0100 message: Merge dbus-bridge. added: extra/conf/upstart-dbus-bridge.conf extra/man/dbus-event.7 extra/man/upstart-dbus-bridge.8 extra/upstart-dbus-bridge.c modified: ChangeLog extra/Makefile.am
-- lp:upstart https://code.launchpad.net/~upstart-devel/upstart/trunk Your team Upstart Reviewers is subscribed to branch lp:upstart. To unsubscribe from this branch go to https://code.launchpad.net/~upstart-devel/upstart/trunk/+edit-subscription
=== modified file 'ChangeLog' --- ChangeLog 2013-06-25 15:56:00 +0000 +++ ChangeLog 2013-06-26 09:15:41 +0000 @@ -1,3 +1,16 @@ +2013-06-26 James Hunt <[email protected]> + + * extra/Makefile.am: Add man pages and conf file. + * extra/upstart-dbus-bridge.c: Only emit events if any jobs care + about them. + * extra/conf/upstart-dbus-bridge.conf: New configuration file. + * extra/man/dbus-event.7: New man page. + * extra/man/upstart-dbus-bridge.8: New man page. + * extra/upstart-dbus-bridge.c: + - Comments and formatting. + - main(): Default to an appropriate bus. + - signal_filter(): Display signal details when run with --debug. + 2013-06-24 James Hunt <[email protected]> * init/Makefile.am: Added missing json file to TEST_DATA_FILES. === modified file 'extra/Makefile.am' --- extra/Makefile.am 2013-03-11 20:02:18 +0000 +++ extra/Makefile.am 2013-05-01 04:33:35 +0000 @@ -19,19 +19,24 @@ sbin_PROGRAMS = \ upstart-socket-bridge \ upstart-event-bridge \ - upstart-file-bridge + upstart-file-bridge \ + upstart-dbus-bridge dist_init_DATA = \ conf/upstart-socket-bridge.conf \ conf/upstart-event-bridge.conf \ - conf/upstart-file-bridge.conf + conf/upstart-file-bridge.conf \ + conf/upstart-dbus-bridge.conf +# FIXME: add man/upstart-dbus-bridge.8 dist_man_MANS = \ man/upstart-socket-bridge.8 \ man/upstart-event-bridge.8 \ man/upstart-file-bridge.8 \ + man/upstart-dbus-bridge.8 \ man/socket-event.7 \ - man/file-event.7 + man/file-event.7 \ + man/dbus-event.7 upstart_socket_bridge_SOURCES = \ upstart-socket-bridge.c @@ -66,6 +71,17 @@ $(NIH_DBUS_LIBS) \ $(DBUS_LIBS) +upstart_dbus_bridge_SOURCES = \ + upstart-dbus-bridge.c +nodist_upstart_dbus_bridge_SOURCES = \ + $(com_ubuntu_Upstart_OUTPUTS) \ + $(com_ubuntu_Upstart_Job_OUTPUTS) +upstart_dbus_bridge_LDADD = \ + $(LTLIBINTL) \ + $(NIH_LIBS) \ + $(NIH_DBUS_LIBS) \ + $(DBUS_LIBS) + if HAVE_UDEV dist_init_DATA += \ conf/upstart-udev-bridge.conf === added file 'extra/conf/upstart-dbus-bridge.conf' --- extra/conf/upstart-dbus-bridge.conf 1970-01-01 00:00:00 +0000 +++ extra/conf/upstart-dbus-bridge.conf 2013-05-01 04:33:35 +0000 @@ -0,0 +1,17 @@ +# upstart-dbus-bridge - Bridge D-Bus signal events into upstart +# +# This helper daemon receives D-Bus signal events and +# emits equivalent Upstart events. + +description "Bridge D-Bus signal events into upstart" + +emits dbus + +start on startup + +stop on runlevel [!2345] + +expect daemon +respawn + +exec upstart-dbus-bridge --daemon --system === added file 'extra/man/dbus-event.7' --- extra/man/dbus-event.7 1970-01-01 00:00:00 +0000 +++ extra/man/dbus-event.7 2013-05-01 04:33:35 +0000 @@ -0,0 +1,53 @@ +.TH dbus\-event 7 2013-04-25 upstart +.\" +.SH NAME +dbus \- event signalling that a dbus signal has been emitted +.\" +.SH SYNOPSIS +.B dbus +.BI SIGNAL\fR= SIGNAL +.BI INTERFACE\fR= INTERFACE +.BI PATH\fR= PATH +.BI SENDER\fR= SENDER +.BI DESTINATION\fR= DESTINATION +.\" +.SH DESCRIPTION + +The +.B dbus +event is generated by the +.BR upstart\-dbus\-bridge (8) +daemon when a D-Bus signal is emitted whose details match the +.I dbus +event condition and environment specified in a job's +.B start on +or +.B stop on +stanza is modified. + +.\" +.SH EXAMPLES +.\" +.IP "start on dbus SIGNAL=NameAcquired INTERFACE=org.freedesktop.DBus PATH=/org/freedesktop/DBus SENDER=org.freedesktop.DBus" +Start job when a particular +.I NameAcquired +D-Bus signal is received. +.\" +.SH AUTHOR +Written by James Hunt +.RB < [email protected] > +.\" +.SH BUGS +Report bugs at +.RB < https://launchpad.net/upstart/+bugs > +.\" +.SH COPYRIGHT +Copyright \(co 2013 Canonical Ltd. +.PP +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +.\" +.SH SEE ALSO +.BR init (5) +.BR init (8) +.BR upstart\-dbus\-bridge (8) === added file 'extra/man/upstart-dbus-bridge.8' --- extra/man/upstart-dbus-bridge.8 1970-01-01 00:00:00 +0000 +++ extra/man/upstart-dbus-bridge.8 2013-05-01 04:57:37 +0000 @@ -0,0 +1,84 @@ +.TH upstart\-dbus\-bridge 8 2013-04-25 upstart +.\" +.SH NAME +upstart\-dbus\-bridge \- Bridge between Upstart and D-Bus +.\" +.SH SYNOPSIS +.B upstart\-dbus\-bridge +.RI [ OPTIONS ]... +.\" +.SH DESCRIPTION +.B upstart\-dbus\-bridge +receives information about D-Bus signals +and creates +.BR init (8) +events for them. + +With no options, monitors signals on the D-Bus system bus and emits +an Upstart event called +.I dbus +via a D-Bus system bus connection to Upstart. + +When run with \fB\-\-user\fP, monitors signals on the users D-Bus session bus +and emits Upstart events via the private D-Bus connection to the users Session Init. + +See \fBdbus\-daemon\fP(1) and for further details. + +.\" +.SH OPTIONS +.\" +.TP +.B \-\-always +Always emit events on receipt of D-Bus signal regardless of whether jobs +care about them. +.TP +.B \-\-daemon +Detach and run in the background. +.\" +.TP +.B \-\-debug +Enable debugging output. +.\" +.TP +.B \-\-help +Show brief usage summary. +.\" +.TP +.B \-\-session +Monitor signals on the D-Bus session bus. +.\" +.TP +.B \-\-system +Monitor signals on the D-Bus system bus. +.\" +.TP +.B \-\-user +User-session mode: connect to Upstart via the user session rather than +over the D\-Bus system bus. +.\" +.TP +.B \-\-verbose +Enable verbose output. +.\" +.SH RESTRICTIONS +D-Bus signals emitted by Upstart itself are ignored. + +.\" +.SH AUTHOR +Written by James Hunt +.RB < [email protected] > +.\" +.SH BUGS +Report bugs at +.RB < https://launchpad.net/ubuntu/+source/upstart/+bugs > +.\" +.SH COPYRIGHT +Copyright \(co 2013 Canonical Ltd. +.PP +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.BR dbus\-daemon (1) +.BR dbus\-event (7) +.BR init (5) +.BR init (8) === added file 'extra/upstart-dbus-bridge.c' --- extra/upstart-dbus-bridge.c 1970-01-01 00:00:00 +0000 +++ extra/upstart-dbus-bridge.c 2013-06-26 09:15:41 +0000 @@ -0,0 +1,640 @@ +/* upstart + * + * Copyright © 2013 Canonical Ltd. + * Author: James Hunt <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif /* HAVE_CONFIG_H */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include <nih/macros.h> +#include <nih/alloc.h> +#include <nih/string.h> +#include <nih/hash.h> +#include <nih/io.h> +#include <nih/option.h> +#include <nih/main.h> +#include <nih/logging.h> +#include <nih/error.h> + +#include <nih-dbus/dbus_connection.h> +#include <nih-dbus/dbus_proxy.h> + +#include "dbus/upstart.h" +#include "com.ubuntu.Upstart.h" +#include "com.ubuntu.Upstart.Job.h" + +/** + * DBUS_EVENT: + * + * Name of event this program handles. + **/ +#define DBUS_EVENT "dbus" + +/* Prototypes for static functions */ +static int dbus_bus_setter (NihOption *option, const char *arg); +static void dbus_disconnected (DBusConnection *connection); +static void upstart_disconnected (DBusConnection *connection); +static DBusHandlerResult signal_filter (DBusConnection *connection, + DBusMessage *message, void *user_data); +static void emit_event_error (void *data, NihDBusMessage *message); +static void upstart_job_added (void *data, NihDBusMessage *message, + const char *job); +static void upstart_job_removed (void *data, NihDBusMessage *message, + const char *job); + +/** + * daemonise: + * + * Set to TRUE if we should become a daemon, rather than just running + * in the foreground. + **/ +static int daemonise = FALSE; + +/** + * upstart: + * + * Proxy to Upstart daemon. + **/ +static NihDBusProxy *upstart = NULL; + +/** + * user_mode: + * + * If TRUE, connect to Session Init rather than PID 1. + **/ +static int user_mode = FALSE; + +/** + * dbus_bus: + * + * type of D-Bus bus to connect to. + **/ +DBusBusType dbus_bus = (DBusBusType)-1; + +/** + * Structure we use for tracking jobs + * + * @entry: list header, + * @path: D-Bus path of job being tracked. + **/ +typedef struct job { + NihList entry; + char *path; +} Job; + +/** + * jobs: + * + * Jobs that we're monitoring. + **/ +static NihHash *jobs = NULL; + +/** + * always: + * + * If TRUE, always emit Upstart events, regardless of whether + * existing jobs care about DBUS_EVENT. + */ +static int always = FALSE; + +/** + * options: + * + * Command-line options accepted by this program. + **/ +static NihOption options[] = { + { 0, "always", N_("Always emit an event on receipt of D-Bus signal"), + NULL, NULL, &always, NULL }, + { 0, "daemon", N_("Detach and run in the background"), + NULL, NULL, &daemonise, NULL }, + { 0, "user", N_("Connect to user session"), + NULL, NULL, &user_mode, NULL }, + { 0, "session", N_("Use D-Bus session bus"), + NULL, NULL, NULL, dbus_bus_setter }, + { 0, "system", N_("Use D-Bus system bus"), + NULL, NULL, NULL, dbus_bus_setter }, + + NIH_OPTION_LAST +}; + + +int +main (int argc, + char *argv[]) +{ + char **args; + DBusConnection *dbus_connection; + DBusConnection *connection; + int ret; + char *pidfile_path = NULL; + char *pidfile = NULL; + char *user_session_addr = NULL; + nih_local char **user_session_path = NULL; + char *path_element = NULL; + DBusError error; + char **job_class_paths; + + nih_main_init (argv[0]); + + nih_option_set_synopsis (_("Bridge D-Bus signals into upstart")); + nih_option_set_help ( + _("By default, upstart-event-bridge does not detach from the " + "console and remains in the foreground. Use the --daemon " + "option to have it detach.")); + + args = nih_option_parser (NULL, argc, argv, options, FALSE); + if (! args) + exit (EXIT_FAILURE); + + dbus_error_init (&error); + + /* Default to an appropriate bus */ + if (dbus_bus == (DBusBusType)-1) + dbus_bus = user_mode ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM; + + /* Connect to the chosen D-Bus bus */ + dbus_connection = NIH_SHOULD (nih_dbus_bus (dbus_bus, dbus_disconnected)); + + if (! dbus_connection) { + NihError *err; + + err = nih_error_get (); + nih_fatal ("%s: %s", _("Could not connect to D-Bus"), + err->message); + nih_free (err); + + exit (EXIT_FAILURE); + } + + dbus_bus_add_match (dbus_connection, "type='signal'", &error); + + if (dbus_error_is_set (&error)) { + nih_fatal ("%s: %s %s", _("Could not add D-Bus signal match"), + error.name, error.message); + dbus_error_free (&error); + + exit (EXIT_FAILURE); + } + + dbus_connection_add_filter (dbus_connection, signal_filter, NULL, NULL); + + dbus_error_free (&error); + + if (user_mode) { + user_session_addr = getenv ("UPSTART_SESSION"); + if (! user_session_addr) { + nih_fatal (_("UPSTART_SESSION is not set in environment")); + exit (EXIT_FAILURE); + } + } + + connection = NIH_SHOULD (nih_dbus_connect (user_mode + ? user_session_addr + : DBUS_ADDRESS_UPSTART, + upstart_disconnected)); + + if (! connection) { + NihError *err; + + err = nih_error_get (); + nih_fatal ("%s: %s", _("Could not connect to Upstart"), + err->message); + nih_free (err); + + exit (EXIT_FAILURE); + } + + /* Allocate jobs hash table */ + jobs = NIH_MUST (nih_hash_string_new (NULL, 0)); + + upstart = NIH_SHOULD (nih_dbus_proxy_new (NULL, connection, + NULL, DBUS_PATH_UPSTART, + NULL, NULL)); + + if (! upstart) { + NihError *err; + + err = nih_error_get (); + nih_fatal ("%s: %s", _("Could not create Upstart proxy"), + err->message); + nih_free (err); + + exit (EXIT_FAILURE); + } + + /* Connect signals to be notified when jobs come and go */ + if (! nih_dbus_proxy_connect (upstart, &upstart_com_ubuntu_Upstart0_6, "JobAdded", + (NihDBusSignalHandler)upstart_job_added, NULL)) { + NihError *err; + + err = nih_error_get (); + nih_fatal ("%s: %s", _("Could not create JobAdded signal connection"), + err->message); + nih_free (err); + + exit (EXIT_FAILURE); + } + + if (! nih_dbus_proxy_connect (upstart, &upstart_com_ubuntu_Upstart0_6, "JobRemoved", + (NihDBusSignalHandler)upstart_job_removed, NULL)) { + NihError *err; + + err = nih_error_get (); + nih_fatal ("%s: %s", _("Could not create JobRemoved signal connection"), + err->message); + nih_free (err); + + exit (EXIT_FAILURE); + } + + /* Request a list of all current jobs */ + if (upstart_get_all_jobs_sync (NULL, upstart, &job_class_paths) < 0) { + NihError *err; + + err = nih_error_get (); + nih_fatal ("%s: %s", _("Could not obtain job list"), + err->message); + nih_free (err); + + exit (EXIT_FAILURE); + } + + for (char **job_class_path = job_class_paths; + job_class_path && *job_class_path; job_class_path++) + upstart_job_added (NULL, NULL, *job_class_path); + + nih_free (job_class_paths); + + /* Become daemon */ + if (daemonise) { + /* Deal with the pidfile location when becoming a daemon. + * We need to be able to run one bridge per upstart daemon. + * Store the PID file in XDG_RUNTIME_DIR or HOME and include the pid of + * the Upstart instance (last part of the DBus path) in the filename. + */ + + if (user_mode) { + /* Extract PID from UPSTART_SESSION */ + user_session_path = nih_str_split (NULL, user_session_addr, "/", TRUE); + for (int i = 0; user_session_path[i] != NULL; i++) + path_element = user_session_path[i]; + + if (! path_element) { + nih_fatal (_("Invalid value for UPSTART_SESSION")); + exit (EXIT_FAILURE); + } + + pidfile_path = getenv ("XDG_RUNTIME_DIR"); + if (! pidfile_path) + pidfile_path = getenv ("HOME"); + + if (pidfile_path) { + NIH_MUST (nih_strcat_sprintf (&pidfile, NULL, "%s/upstart-dbus-bridge.%s.pid", + pidfile_path, path_element)); + nih_main_set_pidfile (pidfile); + } + } + + if (nih_main_daemonise () < 0) { + NihError *err; + + err = nih_error_get (); + nih_fatal ("%s: %s", _("Unable to become daemon"), + err->message); + nih_free (err); + + exit (EXIT_FAILURE); + } + } + + /* Handle TERM and INT signals gracefully */ + nih_signal_set_handler (SIGTERM, nih_signal_handler); + NIH_MUST (nih_signal_add_handler (NULL, SIGTERM, nih_main_term_signal, NULL)); + + if (! daemonise) { + nih_signal_set_handler (SIGINT, nih_signal_handler); + NIH_MUST (nih_signal_add_handler (NULL, SIGINT, nih_main_term_signal, NULL)); + } + + ret = nih_main_loop (); + + /* Destroy any PID file we may have created */ + if (daemonise) { + nih_main_unlink_pidfile(); + } + + return ret; +} + +/** + * dbus_disconnected: + * + * @connection: connection to a D-Bus bus. + * + * Handler called when bridge disconnected from D-Bus. + **/ +static void +dbus_disconnected (DBusConnection *connection) +{ + nih_fatal (_("Disconnected from D-Bus")); + nih_main_loop_exit (EXIT_FAILURE); +} + +/** + * upstart_disconnected: + * + * @connection: connection to Upstart. + * + * Handler called when bridge disconnected from Upstart. + **/ +static void +upstart_disconnected (DBusConnection *connection) +{ + nih_fatal (_("Disconnected from Upstart")); + nih_main_loop_exit (EXIT_FAILURE); +} + +/** + * NihOption setter function to handle selection of D-Bus bus type. + * + * Returns: 0 on success, -1 on invalid console type. + **/ +static int +dbus_bus_setter (NihOption *option, const char *arg) +{ + nih_assert (option); + nih_assert (option->long_option); + + if (! strcmp (option->long_option, "session")) { + dbus_bus = DBUS_BUS_SESSION; + } else { + dbus_bus = DBUS_BUS_SYSTEM; + } + + return 0; +} + +/** + * signal_filter: + * @connection: D-Bus connection, + * @message: D-Bus message, + * @user_data: unused. + * + * Handle D-Bus signal message by emitting an Upstart event + * containing pertinent details from the original message. + * + * Returns: DBUS_HANDLER_RESULT_HANDLED always. + **/ +static DBusHandlerResult +signal_filter (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + int emit = FALSE; + DBusPendingCall *pending_call; + DBusError error; + nih_local char **env = NULL; + const char *sender; + const char *destination; + const char *interface; + const char *signal; + const char *path; + size_t env_len = 0; + + nih_assert (connection); + nih_assert (message); + + if (! always) { + NIH_HASH_FOREACH (jobs, iter) { + emit = TRUE; + break; + } + + /* No jobs care about DBUS_EVENT, so ignore it */ + if (! emit) + goto out; + } + + dbus_error_init (&error); + + sender = dbus_message_get_sender (message); + signal = dbus_message_get_member (message); + interface = dbus_message_get_interface (message); + path = dbus_message_get_path (message); + destination = dbus_message_get_destination (message); + + /* Don't react to D-Bus signals generated by Upstart + * to avoid a possible feedback loop: for example, imagine a job + * that emits an event when it detects (via this bridge) that + * Upstart has emitted an event by considering Upstarts + * "EventEmitted" D-Bus signal interface... + */ + if ((sender && ! strcmp (sender, DBUS_SERVICE_UPSTART)) || + (interface && ! strcmp (interface, DBUS_INTERFACE_UPSTART))) { + nih_debug ("ignoring signal originating from upstart itself"); + goto out; + } + + env = NIH_MUST (nih_str_array_new (NULL)); + + if (signal) { + nih_local char *var = NULL; + var = NIH_MUST (nih_sprintf (NULL, "SIGNAL=%s", signal)); + NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); + } else { + /* We need something to work with */ + nih_debug ("Ignoring message with no signal name"); + goto out; + } + + if (interface) { + nih_local char *var = NULL; + var = NIH_MUST (nih_sprintf (NULL, "INTERFACE=%s", interface)); + NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); + } + + if (path) { + nih_local char *var = NULL; + var = NIH_MUST (nih_sprintf (NULL, "PATH=%s", path)); + NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); + } + + if (sender) { + nih_local char *var = NULL; + var = NIH_MUST (nih_sprintf (NULL, "SENDER=%s", sender)); + NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); + } + + if (destination) { + nih_local char *var = NULL; + var = NIH_MUST (nih_sprintf (NULL, "DESTINATION=%s", destination)); + NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); + } + + nih_debug ("Received D-Bus signal: %s " + "(sender=%s, destination=%s, interface=%s, path=%s)", + signal ? signal : "", + sender ? sender : "", + destination ? destination : "", + interface ? interface : "", + path ? path : ""); + + pending_call = upstart_emit_event (upstart, + DBUS_EVENT, env, FALSE, + NULL, emit_event_error, NULL, + NIH_DBUS_TIMEOUT_NEVER); + + if (! pending_call) { + NihError *err; + err = nih_error_get (); + nih_warn ("%s", err->message); + nih_free (err); + } + + dbus_pending_call_unref (pending_call); + +out: + return DBUS_HANDLER_RESULT_HANDLED; +} + +static void +emit_event_error (void *data, + NihDBusMessage *message) +{ + NihError *err; + + err = nih_error_get (); + nih_warn ("%s", err->message); + nih_free (err); +} + +static void +upstart_job_added (void *data, + NihDBusMessage *message, + const char *job_class_path) +{ + /* set to TRUE if jobs start/stop conditions specify + * DBUS_EVENT. Used to restrict emission of events + * unnecessarily. Note that event environment matching + * though is handled by Upstart. + */ + int add = FALSE; + + Job *job; + nih_local NihDBusProxy *job_class = NULL; + nih_local char ***start_on = NULL; + nih_local char ***stop_on = NULL; + + nih_assert (job_class_path != NULL); + + /* Obtain a proxy to the job */ + job_class = nih_dbus_proxy_new (NULL, upstart->connection, + upstart->name, job_class_path, + NULL, NULL); + if (! job_class) { + NihError *err; + + err = nih_error_get (); + nih_error ("Could not create proxy for job %s: %s", + job_class_path, err->message); + nih_free (err); + + return; + } + + job_class->auto_start = FALSE; + + /* Obtain the start_on and stop_on properties of the job */ + if (job_class_get_start_on_sync (NULL, job_class, &start_on) < 0) { + NihError *err; + + err = nih_error_get (); + nih_error ("Could not obtain job start condition %s: %s", + job_class_path, err->message); + nih_free (err); + + return; + } + + if (job_class_get_stop_on_sync (NULL, job_class, &stop_on) < 0) { + NihError *err; + + err = nih_error_get (); + nih_error ("Could not obtain job stop condition %s: %s", + job_class_path, err->message); + nih_free (err); + + return; + } + + /* Find out whether this job listens for any DBUS events */ + for (char ***event = start_on; event && *event && **event; event++) + if (! strcmp (**event, DBUS_EVENT)) { + add = TRUE; + break; + } + + for (char ***event = stop_on; ! add && event && *event && **event; event++) + if (! strcmp (**event, DBUS_EVENT)) { + add = TRUE; + break; + } + + if (! add) + return; + + nih_debug ("Job got added %s for event %s", job_class_path, DBUS_EVENT); + + /* Free any existing record for the job (should never happen, + * but worth being safe). + */ + job = (Job *)nih_hash_lookup (jobs, job_class_path); + if (job) + nih_free (job); + + /* Create new record for the job */ + job = NIH_MUST (nih_new (NULL, Job)); + job->path = NIH_MUST (nih_strdup (job, job_class_path)); + + nih_list_init (&job->entry); + nih_alloc_set_destructor (job, nih_list_destroy); + nih_hash_add (jobs, &job->entry); +} + +static void +upstart_job_removed (void *data, + NihDBusMessage *message, + const char *job_path) +{ + Job *job; + + nih_assert (job_path != NULL); + + job = (Job *)nih_hash_lookup (jobs, job_path); + if (job) { + nih_debug ("Job went away %s", job_path); + nih_free (job); + } +} +
-- upstart-devel mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/upstart-devel
