int main(int argc, char *argv[]) { sd_bus_slot *slot = NULL; int r; char *mode = NULL; /* Connect to system bus */ // r = sd_bus_open_user(&bus); r = sd_bus_open_system(&bus); if (r < 0) { fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r)); goto finish; } r = sd_bus_add_match(bus, &slot, FILTER, bus_signal_cb, NULL); if (r < 0) { fprintf(stderr, "Failed: sd_bus_add_match: %s : %s\n", strerror(-r), FILTER); goto finish; } r = sd_bus_add_match(bus, &slot, FILTER2, greeting, NULL); if (r < 0) { fprintf(stderr, "Failed: %d sd_bus_add_match: %s : %s\n", __LINE__, strerror(-r), FILTER); goto finish; } for (;;) { /* Process requests */ r = sd_bus_process(bus, NULL); if (r < 0) { fprintf(stderr, "Failed to process bus: %s\n", strerror(-r)); goto finish; } if (r > 0) { continue; } r = sd_bus_wait(bus, (uint64_t) - 1); if (r < 0) { fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r)); goto finish; } } finish: sd_bus_slot_unref(slot); sd_bus_unref(bus); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; }
int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name) { _cleanup_free_ char *match = NULL; int r; assert(e); assert(bus); assert(name); r = asprintf(&match, "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameLost',arg0='%s'", name); if (r < 0) return r; r = sd_bus_add_match(bus, match, quit_callback, e); if (r < 0) return r; r = sd_bus_release_name(bus, name); if (r < 0) return r; if (r != BUS_NAME_RELEASED) return -EIO; return 0; }
static int connect_bus(void) { int r; sd_bus *bus = NULL; struct source_ctx *s; r = sd_bus_default_system(&bus); SOL_INT_CHECK(r, < 0, r); s = sol_mainloop_source_get_data(_ctx.mainloop_source); r = sd_bus_attach_event(bus, s->event, SD_EVENT_PRIORITY_NORMAL); SOL_INT_CHECK_GOTO(r, < 0, fail); r = sd_bus_add_match(bus, NULL, "type='signal'," "sender='org.freedesktop.DBus.Local'," "interface='org.freedesktop.DBus.Local'," "member='Disconnected'", _match_disconnected, &_ctx); SOL_INT_CHECK_GOTO(r, < 0, fail); _ctx.bus = bus; return 0; fail: sd_bus_unref(bus); return r; }
static int client_acquire(Context *context, uint64_t id, Client **_c) { char *watch = NULL; Client *c; int r; assert(context); assert(_c); c = hashmap_get(context->clients, &id); if (c) { *_c = c; return 0; } if (hashmap_size(context->clients) >= CLIENTS_MAX) return -ENOBUFS; r = hashmap_ensure_allocated(&context->clients, uint64_hash_func, uint64_compare_func); if (r < 0) return r; c = new0(Client, 1); if (!c) return -ENOMEM; c->id = id; r = hashmap_put(context->clients, &c->id, c); if (r < 0) goto fail; c->context = context; if (asprintf(&watch, "type='signal'," "sender='org.freedesktop.DBus'," "path='/org/freedesktop/DBus'," "interface='org.freedesktop.DBus'," "member='NameOwnerChanged'," "arg0=':1.%llu'", (unsigned long long) id) < 0) { r = -ENOMEM; goto fail; } r = sd_bus_add_match(context->bus, watch, on_name_owner_changed, c); if (r < 0) { free(watch); goto fail; } c->watch = watch; *_c = c; return 0; fail: client_free(c); return r; }
static void test_one( const char *path, const char *interface, const char *member, const char *arg0, const char *match, bool good) { _cleanup_close_ int bus_ref = -1; _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; sd_bus *a, *b; int r; assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0); bus_ref = bus_kernel_create_bus(name, false, &bus_name); if (bus_ref == -ENOENT) exit(EXIT_TEST_SKIP); assert_se(bus_ref >= 0); address = strappend("kernel:path=", bus_name); assert_se(address); r = sd_bus_new(&a); assert_se(r >= 0); r = sd_bus_new(&b); assert_se(r >= 0); r = sd_bus_set_address(a, address); assert_se(r >= 0); r = sd_bus_set_address(b, address); assert_se(r >= 0); r = sd_bus_start(a); assert_se(r >= 0); r = sd_bus_start(b); assert_se(r >= 0); log_debug("match"); r = sd_bus_add_match(b, NULL, match, NULL, NULL); assert_se(r >= 0); log_debug("signal"); r = sd_bus_emit_signal(a, path, interface, member, "s", arg0); assert_se(r >= 0); r = sd_bus_process(b, &m); assert_se(r >= 0 && (good == !!m)); sd_bus_unref(a); sd_bus_unref(b); }
static void test_proxy_matched(void) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *a = NULL; _cleanup_free_ char *matchstr = NULL; TestProxyMatch match = {}; const char *me; int r; /* open bus 'a' */ r = sd_bus_new(&a); assert_se(r >= 0); r = sd_bus_set_address(a, "unix:path=/var/run/dbus/system_bus_socket"); assert_se(r >= 0); r = sd_bus_set_bus_client(a, true); assert_se(r >= 0); r = sd_bus_start(a); assert_se(r >= 0); r = sd_bus_get_unique_name(a, &me); assert_se(r >= 0); matchstr = strjoin("type='signal'," "member='NameAcquired'," "destination='", me, "'", NULL); assert_se(matchstr); r = sd_bus_add_match(a, NULL, matchstr, test_proxy_acquired, &match); assert_se(r >= 0); r = sd_bus_get_unique_name(a, &match.sender); assert_se(r >= 0); /* barrier to guarantee proxy/dbus-daemon handled the previous data */ r = sd_bus_call_method(a, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "GetId", NULL, NULL, NULL); assert_se(r >= 0); /* now we can be sure the Name* signals were sent */ do { r = sd_bus_process(a, NULL); } while (r > 0); assert_se(r == 0); assert_se(match.matched_acquired == 1); }
static int kbdctx_setup_bus(kbdctx *kc) { int r; r = sd_bus_add_match(kc->context->sysbus, &kc->slot_locale_props_changed, "type='signal'," "sender='org.freedesktop.locale1'," "interface='org.freedesktop.DBus.Properties'," "member='PropertiesChanged'," "path='/org/freedesktop/locale1'", kbdctx_locale_props_changed_fn, kc); if (r < 0) return log_debug_errno(r, "idev-keyboard: cannot setup locale1 link: %m"); return kbdctx_query_locale(kc); }
_public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) { _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL; _cleanup_free_ char *n = NULL; const char *match; int r; assert_return(track, -EINVAL); assert_return(service_name_is_valid(name), -EINVAL); r = hashmap_ensure_allocated(&track->names, &string_hash_ops); if (r < 0) return r; n = strdup(name); if (!n) return -ENOMEM; /* First, subscribe to this name */ match = MATCH_FOR_NAME(n); r = sd_bus_add_match(track->bus, &slot, match, on_name_owner_changed, track); if (r < 0) return r; r = hashmap_put(track->names, n, slot); if (r == -EEXIST) return 0; if (r < 0) return r; /* Second, check if it is currently existing, or maybe * doesn't, or maybe disappeared already. */ r = sd_bus_get_name_creds(track->bus, n, 0, NULL); if (r < 0) { hashmap_remove(track->names, n); return r; } n = NULL; slot = NULL; bus_track_remove_from_queue(track); track->modified = true; return 1; }
int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) { _cleanup_free_ char *match = NULL; const char *unique; int r; assert(e); assert(bus); assert(name); /* We unregister the name here and then wait for the * NameOwnerChanged signal for this event to arrive before we * quit. We do this in order to make sure that any queued * requests are still processed before we really exit. */ r = sd_bus_get_unique_name(bus, &unique); if (r < 0) return r; r = asprintf(&match, "sender='org.freedesktop.DBus'," "type='signal'," "interface='org.freedesktop.DBus'," "member='NameOwnerChanged'," "path='/org/freedesktop/DBus'," "arg0='%s'," "arg1='%s'," "arg2=''", name, unique); if (r < 0) return -ENOMEM; r = sd_bus_add_match(bus, NULL, match, name_owner_change_callback, e); if (r < 0) return r; r = sd_bus_release_name(bus, name); if (r < 0) return r; return 0; }
/* adds a afb-dbus-service client api */ int afb_api_dbus_add_client(const char *path) { int rc; struct api_dbus *api; struct afb_api afb_api; char *match; /* create the dbus client api */ api = make_api_dbus(path); if (api == NULL) goto error; /* connect to events */ rc = asprintf(&match, "type='signal',path='%s',interface='%s',member='event'", api->path, api->name); if (rc < 0) { errno = ENOMEM; ERROR("out of memory"); goto error; } rc = sd_bus_add_match(api->sdbus, &api->slot, match, api_dbus_client_on_event, api); free(match); if (rc < 0) { errno = -rc; ERROR("can't add dbus object %s for %s", api->path, api->name); goto error; } /* record it as an API */ afb_api.closure = api; afb_api.call = (void*)api_dbus_client_call; if (afb_apis_add(api->api, afb_api) < 0) goto error2; return 0; error2: destroy_api_dbus(api); error: return -1; }
_public_ int sd_bus_match_signal( sd_bus *bus, sd_bus_slot **ret, const char *sender, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata) { const char *expression; assert_return(bus, -EINVAL); assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); assert_return(!sender || service_name_is_valid(sender), -EINVAL); assert_return(!path || object_path_is_valid(path), -EINVAL); assert_return(!interface || interface_name_is_valid(interface), -EINVAL); assert_return(!member || member_name_is_valid(member), -EINVAL); expression = make_expression(sender, path, interface, member); return sd_bus_add_match(bus, ret, expression, callback, userdata); }
static int server_init(sd_bus **_bus) { sd_bus *bus = NULL; sd_id128_t id; int r; const char *unique; assert_se(_bus); r = sd_bus_open_user(&bus); if (r < 0) { log_error_errno(r, "Failed to connect to user bus: %m"); goto fail; } r = sd_bus_get_bus_id(bus, &id); if (r < 0) { log_error_errno(r, "Failed to get server ID: %m"); goto fail; } r = sd_bus_get_unique_name(bus, &unique); if (r < 0) { log_error_errno(r, "Failed to get unique name: %m"); goto fail; } log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id)); log_info("Unique ID: %s", unique); log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h')); r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0); if (r < 0) { log_error_errno(r, "Failed to acquire name: %m"); goto fail; } r = sd_bus_add_fallback(bus, NULL, "/foo/bar", object_callback, NULL); if (r < 0) { log_error_errno(r, "Failed to add object: %m"); goto fail; } r = sd_bus_add_match(bus, NULL, "type='signal',interface='foo.bar',member='Notify'", match_callback, NULL); if (r < 0) { log_error_errno(r, "Failed to add match: %m"); goto fail; } r = sd_bus_add_match(bus, NULL, "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'", match_callback, NULL); if (r < 0) { log_error_errno(r, "Failed to add match: %m"); goto fail; } bus_match_dump(&bus->match_callbacks, 0); *_bus = bus; return 0; fail: if (bus) sd_bus_unref(bus); return r; }
int main(int argc, char *argv[]) { _cleanup_close_ int bus_ref = -1; _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL, *bname = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; const char *ua = NULL, *ub = NULL, *the_string = NULL; sd_bus *a, *b; int r, pipe_fds[2]; const char *nn; log_set_max_level(LOG_DEBUG); assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0); bus_ref = bus_kernel_create_bus(name, false, &bus_name); if (bus_ref == -ENOENT) return EXIT_TEST_SKIP; assert_se(bus_ref >= 0); address = strappend("kernel:path=", bus_name); assert_se(address); r = sd_bus_new(&a); assert_se(r >= 0); r = sd_bus_new(&b); assert_se(r >= 0); r = sd_bus_set_description(a, "a"); assert_se(r >= 0); r = sd_bus_set_address(a, address); assert_se(r >= 0); r = sd_bus_set_address(b, address); assert_se(r >= 0); assert_se(sd_bus_negotiate_timestamp(a, 1) >= 0); assert_se(sd_bus_negotiate_creds(a, true, _SD_BUS_CREDS_ALL) >= 0); assert_se(sd_bus_negotiate_timestamp(b, 0) >= 0); assert_se(sd_bus_negotiate_creds(b, true, 0) >= 0); r = sd_bus_start(a); assert_se(r >= 0); r = sd_bus_start(b); assert_se(r >= 0); assert_se(sd_bus_negotiate_timestamp(b, 1) >= 0); assert_se(sd_bus_negotiate_creds(b, true, _SD_BUS_CREDS_ALL) >= 0); r = sd_bus_get_unique_name(a, &ua); assert_se(r >= 0); printf("unique a: %s\n", ua); r = sd_bus_get_description(a, &nn); assert_se(r >= 0); printf("name of a: %s\n", nn); r = sd_bus_get_unique_name(b, &ub); assert_se(r >= 0); printf("unique b: %s\n", ub); r = sd_bus_get_description(b, &nn); assert_se(r >= 0); printf("name of b: %s\n", nn); assert_se(bus_kernel_get_bus_name(b, &bname) >= 0); assert_se(endswith(bname, name)); r = sd_bus_call_method(a, "this.doesnt.exist", "/foo", "meh.mah", "muh", &error, NULL, "s", "yayayay"); assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_SERVICE_UNKNOWN)); assert_se(r == -EHOSTUNREACH); r = sd_bus_add_match(b, NULL, "interface='waldo.com',member='Piep'", NULL, NULL); assert_se(r >= 0); r = sd_bus_emit_signal(a, "/foo/bar/waldo", "waldo.com", "Piep", "sss", "I am a string", "/this/is/a/path", "and.this.a.domain.name"); assert_se(r >= 0); r = sd_bus_try_close(b); assert_se(r == -EBUSY); r = sd_bus_process_priority(b, -10, &m); assert_se(r == 0); r = sd_bus_process(b, &m); assert_se(r > 0); assert_se(m); bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER); assert_se(sd_bus_message_rewind(m, true) >= 0); r = sd_bus_message_read(m, "s", &the_string); assert_se(r >= 0); assert_se(streq(the_string, "I am a string")); sd_bus_message_unref(m); m = NULL; r = sd_bus_request_name(a, "net.x0pointer.foobar", 0); assert_se(r >= 0); r = sd_bus_message_new_method_call(b, &m, "net.x0pointer.foobar", "/a/path", "an.inter.face", "AMethod"); assert_se(r >= 0); assert_se(pipe2(pipe_fds, O_CLOEXEC) >= 0); assert_se(write(pipe_fds[1], "x", 1) == 1); pipe_fds[1] = safe_close(pipe_fds[1]); r = sd_bus_message_append(m, "h", pipe_fds[0]); assert_se(r >= 0); pipe_fds[0] = safe_close(pipe_fds[0]); r = sd_bus_send(b, m, NULL); assert_se(r >= 0); for (;;) { sd_bus_message_unref(m); m = NULL; r = sd_bus_process(a, &m); assert_se(r > 0); assert_se(m); bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER); assert_se(sd_bus_message_rewind(m, true) >= 0); if (sd_bus_message_is_method_call(m, "an.inter.face", "AMethod")) { int fd; char x; r = sd_bus_message_read(m, "h", &fd); assert_se(r >= 0); assert_se(read(fd, &x, 1) == 1); assert_se(x == 'x'); break; } } r = sd_bus_release_name(a, "net.x0pointer.foobar"); assert_se(r >= 0); r = sd_bus_release_name(a, "net.x0pointer.foobar"); assert_se(r == -ESRCH); r = sd_bus_try_close(a); assert_se(r >= 0); sd_bus_unref(a); sd_bus_unref(b); return 0; }
int main(int argc, char *argv[]) { static const char *matchfmt = "type='signal'," "interface='org.freedesktop.DBus.Properties'," "member='PropertiesChanged'," "arg0='org.openbmc.control.Power'," "path='%s'," "sender='%s'"; static const char *usage = "Usage: %s OBJECTPATH on|off\n"; static const size_t LEN = 256; sd_bus *conn = NULL; sd_event *loop = NULL; sd_bus_slot *slot = NULL; sd_bus_error error = SD_BUS_ERROR_NULL; char *service = NULL; int r, dest = -1, state; char match[LEN]; if(argc < 3) { fprintf(stderr, usage, argv[0]); exit(EXIT_FAILURE); } if(!strcmp(argv[2], "on")) dest = 1; if(!strcmp(argv[2], "off")) dest = 0; if(dest != 0 && dest != 1) { fprintf(stderr, usage, argv[0]); exit(EXIT_FAILURE); } r = sd_bus_default_system(&conn); if(r < 0) { fprintf(stderr, "Error connecting to system bus: %s\n", strerror(-r)); goto finish; } r = mapper_get_service(conn, argv[1], &service); if (r < 0) { fprintf(stderr, "Error obtaining host service: %s\n", strerror(-r)); goto finish; } r = sd_event_default(&loop); if (r < 0) { fprintf(stderr, "Error obtaining event loop: %s\n", strerror(-r)); goto finish; } r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL); if (r < 0) { fprintf(stderr, "Failed to attach system " "bus to event loop: %s\n", strerror(-r)); goto finish; } if(strlen(matchfmt) + strnlen(argv[1], LEN) > LEN) { r = -E2BIG; fprintf(stderr, "Error adding match rule: %s\n", strerror(-r)); goto finish; } sprintf(match, matchfmt, argv[1], service); r = sd_bus_add_match(conn, &slot, match, callback, loop); if(r < 0) { fprintf(stderr, "Error adding match rule: %s\n", strerror(-r)); goto finish; } r = sd_bus_get_property_trivial(conn, service, argv[1], "org.openbmc.control.Power", "pgood", &error, 'i', &state); if(r < 0) { fprintf(stderr, "Error getting property: %s\n", strerror(-r)); goto finish; } if(dest == state) goto finish; r = sd_event_loop(loop); if(r < 0) { fprintf(stderr, "Error starting event loop: %s\n", strerror(-r)); goto finish; } finish: exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); }
int main(int argc, char *argv[]) { _cleanup_close_ int bus_ref = -1; _cleanup_free_ char *bus_name = NULL, *address = NULL; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; const char *ua = NULL, *ub = NULL, *the_string = NULL; sd_bus *a, *b; int r, pipe_fds[2]; log_set_max_level(LOG_DEBUG); bus_ref = bus_kernel_create("deine-mutter", &bus_name); if (bus_ref == -ENOENT) return EXIT_TEST_SKIP; assert_se(bus_ref >= 0); address = strappend("kernel:path=", bus_name); assert_se(address); r = sd_bus_new(&a); assert_se(r >= 0); r = sd_bus_new(&b); assert_se(r >= 0); r = sd_bus_set_address(a, address); assert_se(r >= 0); r = sd_bus_set_address(b, address); assert_se(r >= 0); assert_se(sd_bus_negotiate_attach_comm(a, 1) >= 0); assert_se(sd_bus_negotiate_attach_exe(a, 1) >= 0); assert_se(sd_bus_negotiate_attach_cmdline(a, 1) >= 0); assert_se(sd_bus_negotiate_attach_cgroup(a, 1) >= 0); assert_se(sd_bus_negotiate_attach_caps(a, 1) >= 0); assert_se(sd_bus_negotiate_attach_selinux_context(a, 1) >= 0); assert_se(sd_bus_negotiate_attach_audit(a, 1) >= 0); assert_se(sd_bus_negotiate_attach_comm(b, 1) >= 0); assert_se(sd_bus_negotiate_attach_exe(b, 1) >= 0); assert_se(sd_bus_negotiate_attach_cmdline(b, 1) >= 0); assert_se(sd_bus_negotiate_attach_cgroup(b, 1) >= 0); assert_se(sd_bus_negotiate_attach_caps(b, 1) >= 0); assert_se(sd_bus_negotiate_attach_selinux_context(b, 1) >= 0); assert_se(sd_bus_negotiate_attach_audit(b, 1) >= 0); r = sd_bus_start(a); assert_se(r >= 0); r = sd_bus_start(b); assert_se(r >= 0); r = sd_bus_get_unique_name(a, &ua); assert_se(r >= 0); printf("unique a: %s\n", ua); r = sd_bus_get_unique_name(b, &ub); assert_se(r >= 0); printf("unique b: %s\n", ub); r = sd_bus_add_match(b, "interface='waldo.com',member='Piep'", NULL, NULL); assert_se(r >= 0); r = sd_bus_emit_signal(a, "/foo/bar/waldo", "waldo.com", "Piep", "sss", "I am a string", "/this/is/a/path", "and.this.a.domain.name"); assert_se(r >= 0); r = sd_bus_process(b, &m); assert_se(r > 0); assert_se(m); bus_message_dump(m); assert_se(sd_bus_message_rewind(m, true) >= 0); r = sd_bus_message_read(m, "s", &the_string); assert_se(r >= 0); assert_se(streq(the_string, "I am a string")); sd_bus_message_unref(m); m = NULL; r = sd_bus_request_name(a, "net.x0pointer.foobar", 0); assert_se(r >= 0); r = sd_bus_message_new_method_call(b, "net.x0pointer.foobar", "/a/path", "an.inter.face", "AMethod", &m); assert_se(r >= 0); assert_se(pipe2(pipe_fds, O_CLOEXEC) >= 0); assert_se(write(pipe_fds[1], "x", 1) == 1); close_nointr_nofail(pipe_fds[1]); pipe_fds[1] = -1; r = sd_bus_message_append(m, "h", pipe_fds[0]); assert_se(r >= 0); close_nointr_nofail(pipe_fds[0]); pipe_fds[0] = -1; r = sd_bus_send(b, m, NULL); assert_se(r >= 0); for (;;) { sd_bus_message_unref(m); m = NULL; r = sd_bus_process(a, &m); assert_se(r > 0); assert_se(m); bus_message_dump(m); assert_se(sd_bus_message_rewind(m, true) >= 0); if (sd_bus_message_is_method_call(m, "an.inter.face", "AMethod")) { int fd; char x; r = sd_bus_message_read(m, "h", &fd); assert_se(r >= 0); assert_se(read(fd, &x, 1) == 1); assert_se(x == 'x'); break; } } r = sd_bus_release_name(a, "net.x0pointer.foobar"); assert_se(r >= 0); r = sd_bus_release_name(a, "net.x0pointer.foobar"); assert_se(r == -ESRCH); sd_bus_unref(a); sd_bus_unref(b); return 0; }
static int start_transient_service( sd_bus *bus, char **argv, int *retval) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL; _cleanup_free_ char *service = NULL, *pty_path = NULL; _cleanup_close_ int master = -1; int r; assert(bus); assert(argv); assert(retval); if (arg_pty) { if (arg_transport == BUS_TRANSPORT_LOCAL) { master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY); if (master < 0) return log_error_errno(errno, "Failed to acquire pseudo tty: %m"); r = ptsname_malloc(master, &pty_path); if (r < 0) return log_error_errno(r, "Failed to determine tty name: %m"); if (unlockpt(master) < 0) return log_error_errno(errno, "Failed to unlock tty: %m"); } else if (arg_transport == BUS_TRANSPORT_MACHINE) { _cleanup_(sd_bus_unrefp) sd_bus *system_bus = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *pty_reply = NULL; const char *s; r = sd_bus_default_system(&system_bus); if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); r = sd_bus_call_method(system_bus, "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", "OpenMachinePTY", &error, &pty_reply, "s", arg_host); if (r < 0) { log_error("Failed to get machine PTY: %s", bus_error_message(&error, -r)); return r; } r = sd_bus_message_read(pty_reply, "hs", &master, &s); if (r < 0) return bus_log_parse_error(r); master = fcntl(master, F_DUPFD_CLOEXEC, 3); if (master < 0) return log_error_errno(errno, "Failed to duplicate master fd: %m"); pty_path = strdup(s); if (!pty_path) return log_oom(); } else assert_not_reached("Can't allocate tty via ssh"); } if (!arg_no_block) { r = bus_wait_for_jobs_new(bus, &w); if (r < 0) return log_error_errno(r, "Could not watch jobs: %m"); } if (arg_unit) { r = unit_name_mangle_with_suffix(arg_unit, UNIT_NAME_NOGLOB, ".service", &service); if (r < 0) return log_error_errno(r, "Failed to mangle unit name: %m"); } else { r = make_unit_name(bus, UNIT_SERVICE, &service); if (r < 0) return r; } r = sd_bus_message_new_method_call( bus, &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartTransientUnit"); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); if (r < 0) return bus_log_create_error(r); /* Name and mode */ r = sd_bus_message_append(m, "ss", service, "fail"); if (r < 0) return bus_log_create_error(r); /* Properties */ r = sd_bus_message_open_container(m, 'a', "(sv)"); if (r < 0) return bus_log_create_error(r); r = transient_service_set_properties(m, argv, pty_path); if (r < 0) return bus_log_create_error(r); r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); /* Auxiliary units */ r = sd_bus_message_append(m, "a(sa(sv))", 0); if (r < 0) return bus_log_create_error(r); polkit_agent_open_if_enabled(); r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) return log_error_errno(r, "Failed to start transient service unit: %s", bus_error_message(&error, r)); if (w) { const char *object; r = sd_bus_message_read(reply, "o", &object); if (r < 0) return bus_log_parse_error(r); r = bus_wait_for_jobs_one(w, object, arg_quiet); if (r < 0) return r; } if (!arg_quiet) log_info("Running as unit: %s", service); if (arg_wait || master >= 0) { _cleanup_(run_context_free) RunContext c = {}; c.bus = sd_bus_ref(bus); r = sd_event_default(&c.event); if (r < 0) return log_error_errno(r, "Failed to get event loop: %m"); if (master >= 0) { assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGWINCH, SIGTERM, SIGINT, -1) >= 0); (void) sd_event_add_signal(c.event, NULL, SIGINT, NULL, NULL); (void) sd_event_add_signal(c.event, NULL, SIGTERM, NULL, NULL); if (!arg_quiet) log_info("Press ^] three times within 1s to disconnect TTY."); r = pty_forward_new(c.event, master, PTY_FORWARD_IGNORE_INITIAL_VHANGUP, &c.forward); if (r < 0) return log_error_errno(r, "Failed to create PTY forwarder: %m"); pty_forward_set_handler(c.forward, pty_forward_handler, &c); } if (arg_wait) { _cleanup_free_ char *path = NULL; const char *mt; path = unit_dbus_path_from_name(service); if (!path) return log_oom(); mt = strjoina("type='signal'," "sender='org.freedesktop.systemd1'," "path='", path, "'," "interface='org.freedesktop.DBus.Properties'," "member='PropertiesChanged'"); r = sd_bus_add_match(bus, &c.match, mt, on_properties_changed, &c); if (r < 0) return log_error_errno(r, "Failed to add properties changed signal."); r = sd_bus_attach_event(bus, c.event, 0); if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop."); } r = sd_event_loop(c.event); if (r < 0) return log_error_errno(r, "Failed to run event loop: %m"); if (c.forward) { char last_char = 0; r = pty_forward_get_last_char(c.forward, &last_char); if (r >= 0 && !arg_quiet && last_char != '\n') fputc('\n', stdout); } if (!arg_quiet) { if (!isempty(c.result)) log_info("Finished with result: %s", strna(c.result)); if (c.exit_code == CLD_EXITED) log_info("Main processes terminated with: code=%s/status=%i", sigchld_code_to_string(c.exit_code), c.exit_status); else if (c.exit_code > 0) log_info("Main processes terminated with: code=%s/status=%s", sigchld_code_to_string(c.exit_code), signal_to_string(c.exit_status)); if (c.inactive_enter_usec > 0 && c.inactive_enter_usec != USEC_INFINITY && c.inactive_exit_usec > 0 && c.inactive_exit_usec != USEC_INFINITY && c.inactive_enter_usec > c.inactive_exit_usec) { char ts[FORMAT_TIMESPAN_MAX]; log_info("Service runtime: %s", format_timespan(ts, sizeof(ts), c.inactive_enter_usec - c.inactive_exit_usec, USEC_PER_MSEC)); } if (c.cpu_usage_nsec > 0 && c.cpu_usage_nsec != NSEC_INFINITY) { char ts[FORMAT_TIMESPAN_MAX]; log_info("CPU time consumed: %s", format_timespan(ts, sizeof(ts), (c.cpu_usage_nsec + NSEC_PER_USEC - 1) / NSEC_PER_USEC, USEC_PER_MSEC)); } } /* Try to propagate the service's return value */ if (c.result && STR_IN_SET(c.result, "success", "exit-code") && c.exit_code == CLD_EXITED) *retval = c.exit_status; else *retval = EXIT_FAILURE; } return 0; }
int main(int argc, char *argv[]) { sd_bus_slot *slot = NULL; int r; char *mode = NULL; // Register all the handlers that provider implementation to IPMI commands. ipmi_register_callback_handlers(HOST_IPMI_LIB_PATH); #ifdef __IPMI_DEBUG__ printf("Registered Function handlers:\n"); // Print the registered handlers and their arguments. for(auto& iter : g_ipmid_router_map) { ipmi_fn_cmd_t fn_and_cmd = iter.first; printf("NETFN:[0x%X], cmd[0x%X]\n", fn_and_cmd.first, fn_and_cmd.second); } #endif /* Connect to system bus */ r = sd_bus_open_system(&bus); if (r < 0) { fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r)); goto finish; } r = sd_bus_add_match(bus, &slot, FILTER, handle_ipmi_command, NULL); if (r < 0) { fprintf(stderr, "Failed: sd_bus_add_match: %s : %s\n", strerror(-r), FILTER); goto finish; } for (;;) { /* Process requests */ r = sd_bus_process(bus, NULL); if (r < 0) { fprintf(stderr, "Failed to process bus: %s\n", strerror(-r)); goto finish; } if (r > 0) { continue; } r = sd_bus_wait(bus, (uint64_t) - 1); if (r < 0) { fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r)); goto finish; } } finish: sd_bus_slot_unref(slot); sd_bus_unref(bus); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; }
int main(int argc, char *argv[]) { sd_bus_slot *slot = NULL; int r; char *mode = NULL; if (argc != 2) { fprintf(stderr, "syntax: %s [server|client]\n", argv[0]); return 1; } mode = argv[1]; /* Connect to system bus */ r = sd_bus_open_system(&bus); if (r < 0) { fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r)); goto finish; } if (!strcmp("server", mode)) { r = sd_bus_add_object_vtable(bus, &slot, OBJ, /* object path */ INT, /* interface name */ signal_vtable, NULL); if (r < 0) { fprintf(stderr, "Failed to issue method call: %s\n", strerror(-r)); goto finish; } /* Take a well-known service name so that clients can find us */ r = sd_bus_request_name(bus, INT, 0); if (r < 0) { fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-r)); goto finish; } } else if (!strcmp("client", mode)) { r = sd_bus_add_match(bus, &slot, FILTER, bus_signal_cb, NULL); if (r < 0) { fprintf(stderr, "Failed: sd_bus_add_match: %s\n", strerror(-r)); goto finish; } } else { fprintf(stderr, "Invalid operating mode %s", mode); return 1; } for (;;) { /* Process requests */ r = sd_bus_process(bus, NULL); if (r < 0) { fprintf(stderr, "Failed to process bus: %s\n", strerror(-r)); goto finish; } if (r > 0) { continue; } r = sd_bus_wait(bus, (uint64_t) - 1); if (r < 0) { fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r)); goto finish; } } finish: sd_bus_slot_unref(slot); sd_bus_unref(bus); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; }
static int manager_connect_bus(Manager *m) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; assert(m); assert(!m->bus); r = sd_bus_default_system(&m->bus); if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", manager_vtable, m); if (r < 0) return log_error_errno(r, "Failed to add manager object vtable: %m"); r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/machine", "org.freedesktop.machine1.Machine", machine_vtable, machine_object_find, m); if (r < 0) return log_error_errno(r, "Failed to add machine object vtable: %m"); r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/machine", machine_node_enumerator, m); if (r < 0) return log_error_errno(r, "Failed to add machine enumerator: %m"); r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/image", "org.freedesktop.machine1.Image", image_vtable, image_object_find, m); if (r < 0) return log_error_errno(r, "Failed to add image object vtable: %m"); r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/image", image_node_enumerator, m); if (r < 0) return log_error_errno(r, "Failed to add image enumerator: %m"); r = sd_bus_add_match(m->bus, NULL, "type='signal'," "sender='org.freedesktop.systemd1'," "interface='org.freedesktop.systemd1.Manager'," "member='JobRemoved'," "path='/org/freedesktop/systemd1'", match_job_removed, m); if (r < 0) return log_error_errno(r, "Failed to add match for JobRemoved: %m"); r = sd_bus_add_match(m->bus, NULL, "type='signal'," "sender='org.freedesktop.systemd1'," "interface='org.freedesktop.systemd1.Manager'," "member='UnitRemoved'," "path='/org/freedesktop/systemd1'", match_unit_removed, m); if (r < 0) return log_error_errno(r, "Failed to add match for UnitRemoved: %m"); r = sd_bus_add_match(m->bus, NULL, "type='signal'," "sender='org.freedesktop.systemd1'," "interface='org.freedesktop.DBus.Properties'," "member='PropertiesChanged'," "arg0='org.freedesktop.systemd1.Unit'", match_properties_changed, m); if (r < 0) return log_error_errno(r, "Failed to add match for PropertiesChanged: %m"); r = sd_bus_add_match(m->bus, NULL, "type='signal'," "sender='org.freedesktop.systemd1'," "interface='org.freedesktop.systemd1.Manager'," "member='Reloading'," "path='/org/freedesktop/systemd1'", match_reloading, m); if (r < 0) return log_error_errno(r, "Failed to add match for Reloading: %m"); r = sd_bus_call_method( m->bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Subscribe", &error, NULL, NULL); if (r < 0) { log_error("Failed to enable subscription: %s", bus_error_message(&error, r)); return r; } r = sd_bus_request_name(m->bus, "org.freedesktop.machine1", 0); if (r < 0) return log_error_errno(r, "Failed to register name: %m"); r = sd_bus_attach_event(m->bus, m->event, 0); if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop: %m"); return 0; }
/* * First of all, creates a transaction; * then reads the newly created bus path, * adds a match to the bus to wait until installation is really finished before notifying the user. * finally, calls InstallFiles method, and processes the bus while finished == 0. */ void *install_package(void *str) { sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus_message *mess = NULL; sd_bus *install_bus = NULL; const char *path; int r, inhibit_fd = -1, finished = 0; r = sd_bus_open_system(&install_bus); if (r < 0) { print_and_warn(strerror(-r), ERR_LINE); goto finish; } INFO("calling CreateTransaction on bus."); r = sd_bus_call_method(install_bus, "org.freedesktop.PackageKit", "/org/freedesktop/PackageKit", "org.freedesktop.PackageKit", "CreateTransaction", &error, &mess, NULL); if (r < 0) { print_and_warn(error.message, ERR_LINE); goto finish; } if (config.inhibit) { inhibit_fd = inhibit_suspend("Package installation..."); } sd_bus_message_read(mess, "o", &path); r = sd_bus_add_match(install_bus, NULL, "type='signal',interface='org.freedesktop.PackageKit.Transaction',member='Finished'", match_callback, &finished); if (r < 0) { print_and_warn(strerror(-r), ERR_LINE); goto finish; } sd_bus_flush(install_bus); INFO("calling InstallFiles on bus."); r = sd_bus_call_method(install_bus, "org.freedesktop.PackageKit", path, "org.freedesktop.PackageKit.Transaction", "InstallFiles", &error, NULL, "tas", 0, 1, (char *)str); if (r < 0) { print_and_warn(error.message, ERR_LINE); goto finish; } while (!finished) { r = sd_bus_process(install_bus, NULL); if (r > 0) { continue; } r = sd_bus_wait(install_bus, (uint64_t) -1); if (r < 0) { break; } } finish: stop_inhibition(inhibit_fd); close_bus(&error, mess, install_bus); pthread_detach(pthread_self()); pthread_exit(NULL); }