Connecting to systemd DBUS signals using gdbus-codegen -
i not able receive systemd dbus signals when using gdbus-codegen generated manager proxy. able call methods provided systemd on dbus.
i searched online , looked these links without success. there aren't examples on how when gdbus-codegen used systemd api.
- https://developer.gnome.org/gio/stable/gdbus-codegen.html
- http://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/gio/ch30s05.html
here did along code snippets.
1) generated systemd introspection , used xml input gdbus-codegen.
...snip
<interface name="org.freedesktop.systemd1.manager"> <signal name="jobremoved"> <arg type="u"/> <arg type="o"/> <arg type="s"/> <arg type="s"/> </signal>
...snip
2) wrote client code use c apis generated gdbus-codegen , created manager proxy. (everything on system bus).
systemdmanager *systemdproxy = systemd_manager_proxy_new_for_bus_sync( g_bus_type_system, g_dbus_proxy_flags_none, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", null, error);
3) define signal handler
static void on_done(gdbusproxy *proxy, gchar *sender_name, gchar *signal_name, gvariant *parameters, gpointer user_data) { log_error("on_done"); }
4) connected signal handler proxy jobremoved signal.
if (g_signal_connect(systemdproxy, "job-removed", g_callback(on_done), null) <= 0 ) { log_error("failed connect signal job-removed"); }
5) used proxy start systemd service. returns success , see unit start , run second or 2 , terminate.
ret = systemd_manager_call_start_unit_sync( systemdproxy, unit_name, unit_mode, &job_obj, null, &error);
6) systemd generates jobremoved signal. dbus-monitor shows it.
signal sender=:1.0 -> dest=(null destination) serial=11931 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.manager; member=jobremoved uint32 7009 object path "/org/freedesktop/systemd1/job/7009" string "mysample.service" string "done"
7) signal handler never gets called. (everything uses system bus, there no other buses). have tried various strings detailed_signal
2nd parameter g_signal_connect
(like: jobremoved
, job_removed
, ::job-removed
, not accepted g_signal_connect
).
any appreciated!
the solution use glib event loop
in program. program did not have running gmainloop
necessary callbacks glib
. not elegant way various reasons decided spawn new thread block on g_main_loop_run. here how looks like.
void *event_loop_thread(void *unused) { gmainloop *loop = g_main_loop_new(null, 0); g_main_loop_run(loop); } int main() { // snip pthread_create(&thread_id, null, event_loop_thread, null); // steps 2 6, , @ step 7 signal handler called }
also had fix signal handler signature compatible signal receive meaningful parameters.
static void on_done(systemdmanager *manager, guint32 job_id, gchar *job_obj, gchar *unit_name, gchar *status) { log_error("on_done"); }
Comments
Post a Comment