man/examples: use strerror() instead of %m
This commit is contained in:
@@ -11,8 +11,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
|
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
errno = -r;
|
fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
|
||||||
fprintf(stderr, "Failed to open journal: %m\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
SD_JOURNAL_FOREACH_FIELD(j, field)
|
SD_JOURNAL_FOREACH_FIELD(j, field)
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int r;
|
int r;
|
||||||
sd_journal *j;
|
sd_journal *j;
|
||||||
|
|
||||||
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
|
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
errno = -r;
|
fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
|
||||||
fprintf(stderr, "Failed to open journal: %m\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
SD_JOURNAL_FOREACH(j) {
|
SD_JOURNAL_FOREACH(j) {
|
||||||
@@ -19,8 +19,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
r = sd_journal_get_data(j, "MESSAGE", (const void **)&d, &l);
|
r = sd_journal_get_data(j, "MESSAGE", (const void **)&d, &l);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
errno = -r;
|
fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
|
||||||
fprintf(stderr, "Failed to read message field: %m\n");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,14 +12,12 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
|
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
errno = -r;
|
fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
|
||||||
fprintf(stderr, "Failed to open journal: %m\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
r = sd_journal_query_unique(j, "_SYSTEMD_UNIT");
|
r = sd_journal_query_unique(j, "_SYSTEMD_UNIT");
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
errno = -r;
|
fprintf(stderr, "Failed to query journal: %s\n", strerror(-r));
|
||||||
fprintf(stderr, "Failed to query journal: %m\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
SD_JOURNAL_FOREACH_UNIQUE(j, d, l)
|
SD_JOURNAL_FOREACH_UNIQUE(j, d, l)
|
||||||
|
|||||||
@@ -7,39 +7,38 @@
|
|||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int r;
|
int r;
|
||||||
sd_journal *j;
|
sd_journal *j;
|
||||||
|
|
||||||
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
|
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
errno = -r;
|
fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
|
||||||
fprintf(stderr, "Failed to open journal: %m\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
const void *d;
|
const void *d;
|
||||||
size_t l;
|
size_t l;
|
||||||
r = sd_journal_next(j);
|
r = sd_journal_next(j);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
errno = -r;
|
fprintf(stderr, "Failed to iterate to next entry: %s\n", strerror(-r));
|
||||||
fprintf(stderr, "Failed to iterate to next entry: %m\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
/* Reached the end, let's wait for changes, and try again */
|
/* Reached the end, let's wait for changes, and try again */
|
||||||
r = sd_journal_wait(j, (uint64_t) -1);
|
r = sd_journal_wait(j, (uint64_t) -1);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
errno = -r;
|
fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
|
||||||
fprintf(stderr, "Failed to wait for changes: %m\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
r = sd_journal_get_data(j, "MESSAGE", &d, &l);
|
r = sd_journal_get_data(j, "MESSAGE", &d, &l);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
errno = -r;
|
fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
|
||||||
fprintf(stderr, "Failed to read message field: %m\n");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
printf("%.*s\n", (int) l, (const char*) d);
|
printf("%.*s\n", (int) l, (const char*) d);
|
||||||
}
|
}
|
||||||
|
|
||||||
sd_journal_close(j);
|
sd_journal_close(j);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,15 +10,16 @@
|
|||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int fd;
|
int fd;
|
||||||
FILE *log;
|
FILE *log;
|
||||||
|
|
||||||
fd = sd_journal_stream_fd("test", LOG_INFO, 1);
|
fd = sd_journal_stream_fd("test", LOG_INFO, 1);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
errno = -fd;
|
fprintf(stderr, "Failed to create stream fd: %s\n", strerror(-fd));
|
||||||
fprintf(stderr, "Failed to create stream fd: %m\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
log = fdopen(fd, "w");
|
log = fdopen(fd, "w");
|
||||||
if (!log) {
|
if (!log) {
|
||||||
fprintf(stderr, "Failed to create file object: %m\n");
|
fprintf(stderr, "Failed to create file object: %s\n", strerror(errno));
|
||||||
close(fd);
|
close(fd);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-17
@@ -43,13 +43,10 @@
|
|||||||
|
|
||||||
#define _cleanup_(f) __attribute__((cleanup(f)))
|
#define _cleanup_(f) __attribute__((cleanup(f)))
|
||||||
|
|
||||||
#define check(log_level, x) ({ \
|
static int log_error(int log_level, int error, const char *str) {
|
||||||
int _r = (x); \
|
sd_journal_print(log_level, "%s failed: %s", str, strerror(-error));
|
||||||
errno = _r < 0 ? -_r : 0; \
|
return error;
|
||||||
sd_journal_print((log_level), #x ": %m"); \
|
}
|
||||||
if (_r < 0) \
|
|
||||||
return EXIT_FAILURE; \
|
|
||||||
})
|
|
||||||
|
|
||||||
typedef enum LogTarget {
|
typedef enum LogTarget {
|
||||||
LOG_TARGET_JOURNAL,
|
LOG_TARGET_JOURNAL,
|
||||||
@@ -193,6 +190,7 @@ int main(int argc, char **argv) {
|
|||||||
.log_target = LOG_TARGET_JOURNAL,
|
.log_target = LOG_TARGET_JOURNAL,
|
||||||
.syslog_identifier = "example",
|
.syslog_identifier = "example",
|
||||||
};
|
};
|
||||||
|
int r;
|
||||||
|
|
||||||
/* https://man7.org/linux/man-pages/man3/setlogmask.3.html
|
/* https://man7.org/linux/man-pages/man3/setlogmask.3.html
|
||||||
* Programs using syslog() instead of sd_journal can use this API to cut logs
|
* Programs using syslog() instead of sd_journal can use this API to cut logs
|
||||||
@@ -203,37 +201,49 @@ int main(int argc, char **argv) {
|
|||||||
/* Acquire a connection to the bus, letting the library work out the details.
|
/* Acquire a connection to the bus, letting the library work out the details.
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_bus_default.html
|
* https://www.freedesktop.org/software/systemd/man/sd_bus_default.html
|
||||||
*/
|
*/
|
||||||
check(o.log_level, sd_bus_default(&bus));
|
r = sd_bus_default(&bus);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(o.log_level, r, "sd_bus_default()");
|
||||||
|
|
||||||
/* Publish an interface on the bus, specifying our well-known object access
|
/* Publish an interface on the bus, specifying our well-known object access
|
||||||
* path and public interface name.
|
* path and public interface name.
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_bus_add_object.html
|
* https://www.freedesktop.org/software/systemd/man/sd_bus_add_object.html
|
||||||
* https://dbus.freedesktop.org/doc/dbus-tutorial.html
|
* https://dbus.freedesktop.org/doc/dbus-tutorial.html
|
||||||
*/
|
*/
|
||||||
check(o.log_level, sd_bus_add_object_vtable(bus, NULL,
|
r = sd_bus_add_object_vtable(bus, NULL,
|
||||||
"/org/freedesktop/LogControl1",
|
"/org/freedesktop/LogControl1",
|
||||||
"org.freedesktop.LogControl1",
|
"org.freedesktop.LogControl1",
|
||||||
vtable,
|
vtable,
|
||||||
&o));
|
&o);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(o.log_level, r, "sd_bus_add_object_vtable()");
|
||||||
|
|
||||||
/* By default the service is assigned an ephemeral name. Also add a fixed
|
/* By default the service is assigned an ephemeral name. Also add a fixed
|
||||||
* one, so that clients know whom to call.
|
* one, so that clients know whom to call.
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_bus_request_name.html
|
* https://www.freedesktop.org/software/systemd/man/sd_bus_request_name.html
|
||||||
*/
|
*/
|
||||||
check(o.log_level, sd_bus_request_name(bus, "org.freedesktop.Example", 0));
|
r = sd_bus_request_name(bus, "org.freedesktop.Example", 0);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(o.log_level, r, "sd_bus_request_name()");
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* https://www.freedesktop.org/software/systemd/man/sd_bus_wait.html
|
/* https://www.freedesktop.org/software/systemd/man/sd_bus_wait.html
|
||||||
*/
|
*/
|
||||||
check(o.log_level, sd_bus_wait(bus, UINT64_MAX));
|
r = sd_bus_wait(bus, UINT64_MAX);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(o.log_level, r, "sd_bus_wait()");
|
||||||
/* https://www.freedesktop.org/software/systemd/man/sd_bus_process.html
|
/* https://www.freedesktop.org/software/systemd/man/sd_bus_process.html
|
||||||
*/
|
*/
|
||||||
check(o.log_level, sd_bus_process(bus, NULL));
|
r = sd_bus_process(bus, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(o.log_level, r, "sd_bus_process()");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://www.freedesktop.org/software/systemd/man/sd_bus_release_name.html
|
/* https://www.freedesktop.org/software/systemd/man/sd_bus_release_name.html
|
||||||
*/
|
*/
|
||||||
check(o.log_level, sd_bus_release_name(bus, "org.freedesktop.Example"));
|
r = sd_bus_release_name(bus, "org.freedesktop.Example");
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(o.log_level, r, "sd_bus_release_name()");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,7 @@
|
|||||||
#define MEMBER "GetUnitByPID"
|
#define MEMBER "GetUnitByPID"
|
||||||
|
|
||||||
static int log_error(int error, const char *message) {
|
static int log_error(int error, const char *message) {
|
||||||
errno = -error;
|
fprintf(stderr, "%s: %s\n", message, strerror(-error));
|
||||||
fprintf(stderr, "%s: %m\n", message);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,7 @@
|
|||||||
#define MEMBER "GetUnitByPID"
|
#define MEMBER "GetUnitByPID"
|
||||||
|
|
||||||
static int log_error(int error, const char *message) {
|
static int log_error(int error, const char *message) {
|
||||||
errno = -error;
|
fprintf(stderr, "%s: %s\n", message, strerror(-error));
|
||||||
fprintf(stderr, "%s: %m\n", message);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,5 +14,5 @@ int writer_with_negative_errno_return(int fd, sd_bus_error *error) {
|
|||||||
|
|
||||||
/* On error, initialize the error structure, and also propagate the errno
|
/* On error, initialize the error structure, and also propagate the errno
|
||||||
* value that write(2) set for us. */
|
* value that write(2) set for us. */
|
||||||
return sd_bus_error_set_errnof(error, errno, "Failed to write to fd %i: %m", fd);
|
return sd_bus_error_set_errnof(error, errno, "Failed to write to fd %i: %s", fd, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,13 +42,10 @@
|
|||||||
|
|
||||||
#define _cleanup_(f) __attribute__((cleanup(f)))
|
#define _cleanup_(f) __attribute__((cleanup(f)))
|
||||||
|
|
||||||
#define check(x) ({ \
|
static int log_error(int r, const char *str) {
|
||||||
int _r = (x); \
|
fprintf(stderr, "%s failed: %s\n", str, strerror(-r));
|
||||||
errno = _r < 0 ? -_r : 0; \
|
return r;
|
||||||
printf(#x ": %m\n"); \
|
}
|
||||||
if (_r < 0) \
|
|
||||||
return EXIT_FAILURE; \
|
|
||||||
})
|
|
||||||
|
|
||||||
typedef struct object {
|
typedef struct object {
|
||||||
const char *example;
|
const char *example;
|
||||||
@@ -90,13 +87,24 @@ static const sd_bus_vtable vtable[] = {
|
|||||||
static int setup(object *o);
|
static int setup(object *o);
|
||||||
|
|
||||||
static int on_disconnect(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
|
static int on_disconnect(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
|
||||||
check(setup((object *)userdata));
|
int r;
|
||||||
return 0;
|
|
||||||
|
r = setup((object *)userdata);
|
||||||
|
if (r < 0) {
|
||||||
|
object *o = userdata;
|
||||||
|
r = sd_event_exit(*o->event, r);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_event_exit()");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure the event loop exits with a clear error if acquiring the well-known
|
/* Ensure the event loop exits with a clear error if acquiring the well-known
|
||||||
* service name fails */
|
* service name fails */
|
||||||
static int request_name_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
|
static int request_name_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
|
||||||
|
int r;
|
||||||
|
|
||||||
if (!sd_bus_message_is_method_error(m, NULL))
|
if (!sd_bus_message_is_method_error(m, NULL))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@@ -105,21 +113,27 @@ static int request_name_callback(sd_bus_message *m, void *userdata, sd_bus_error
|
|||||||
if (sd_bus_error_has_names(error, SD_BUS_ERROR_TIMEOUT, SD_BUS_ERROR_NO_REPLY))
|
if (sd_bus_error_has_names(error, SD_BUS_ERROR_TIMEOUT, SD_BUS_ERROR_NO_REPLY))
|
||||||
return 1; /* The bus is not available, try again later */
|
return 1; /* The bus is not available, try again later */
|
||||||
|
|
||||||
printf("Failed to request name: %s\n", error->message);
|
fprintf(stderr, "Failed to request name: %s\n", error->message);
|
||||||
object *o = userdata;
|
object *o = userdata;
|
||||||
check(sd_event_exit(*o->event, -sd_bus_error_get_errno(error)));
|
r = sd_event_exit(*o->event, -sd_bus_error_get_errno(error));
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_event_exit()");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup(object *o) {
|
static int setup(object *o) {
|
||||||
|
int r;
|
||||||
|
|
||||||
/* If we are reconnecting, then the bus object needs to be closed, detached
|
/* If we are reconnecting, then the bus object needs to be closed, detached
|
||||||
* from the event loop and recreated.
|
* from the event loop and recreated.
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_bus_detach_event.html
|
* https://www.freedesktop.org/software/systemd/man/sd_bus_detach_event.html
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_bus_close_unref.html
|
* https://www.freedesktop.org/software/systemd/man/sd_bus_close_unref.html
|
||||||
*/
|
*/
|
||||||
if (*o->bus) {
|
if (*o->bus) {
|
||||||
check(sd_bus_detach_event(*o->bus));
|
r = sd_bus_detach_event(*o->bus);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_bus_detach_event()");
|
||||||
*o->bus = sd_bus_close_unref(*o->bus);
|
*o->bus = sd_bus_close_unref(*o->bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,55 +149,75 @@ static int setup(object *o) {
|
|||||||
* https://www.freedesktop.org/software/systemd/man/sd_bus_set_connected_signal.html
|
* https://www.freedesktop.org/software/systemd/man/sd_bus_set_connected_signal.html
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_bus_start.html
|
* https://www.freedesktop.org/software/systemd/man/sd_bus_start.html
|
||||||
*/
|
*/
|
||||||
check(sd_bus_new(o->bus));
|
r = sd_bus_new(o->bus);
|
||||||
check(sd_bus_set_address(*o->bus, "unix:path=/run/dbus/system_bus_socket"));
|
if (r < 0)
|
||||||
check(sd_bus_set_bus_client(*o->bus, 1));
|
return log_error(r, "sd_bus_new()");
|
||||||
check(sd_bus_negotiate_creds(*o->bus, 1, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS));
|
r = sd_bus_set_address(*o->bus, "unix:path=/run/dbus/system_bus_socket");
|
||||||
check(sd_bus_set_watch_bind(*o->bus, 1));
|
if (r < 0)
|
||||||
check(sd_bus_start(*o->bus));
|
return log_error(r, "sd_bus_set_address()");
|
||||||
|
r = sd_bus_set_bus_client(*o->bus, 1);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_bus_set_bus_client()");
|
||||||
|
r = sd_bus_negotiate_creds(*o->bus, 1, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_bus_negotiate_creds()");
|
||||||
|
r = sd_bus_set_watch_bind(*o->bus, 1);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_bus_set_watch_bind()");
|
||||||
|
r = sd_bus_start(*o->bus);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_bus_start()");
|
||||||
|
|
||||||
/* Publish an interface on the bus, specifying our well-known object access
|
/* Publish an interface on the bus, specifying our well-known object access
|
||||||
* path and public interface name.
|
* path and public interface name.
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_bus_add_object.html
|
* https://www.freedesktop.org/software/systemd/man/sd_bus_add_object.html
|
||||||
* https://dbus.freedesktop.org/doc/dbus-tutorial.html
|
* https://dbus.freedesktop.org/doc/dbus-tutorial.html
|
||||||
*/
|
*/
|
||||||
check(sd_bus_add_object_vtable(*o->bus,
|
r = sd_bus_add_object_vtable(*o->bus,
|
||||||
NULL,
|
NULL,
|
||||||
"/org/freedesktop/ReconnectExample",
|
"/org/freedesktop/ReconnectExample",
|
||||||
"org.freedesktop.ReconnectExample",
|
"org.freedesktop.ReconnectExample",
|
||||||
vtable,
|
vtable,
|
||||||
o));
|
o);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_bus_add_object_vtable()");
|
||||||
/* By default the service is only assigned an ephemeral name. Also add a
|
/* By default the service is only assigned an ephemeral name. Also add a
|
||||||
* well-known one, so that clients know whom to call. This needs to be
|
* well-known one, so that clients know whom to call. This needs to be
|
||||||
* asynchronous, as D-Bus might not be yet available. The callback will check
|
* asynchronous, as D-Bus might not be yet available. The callback will check
|
||||||
* whether the error is expected or not, in case it fails.
|
* whether the error is expected or not, in case it fails.
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_bus_request_name.html
|
* https://www.freedesktop.org/software/systemd/man/sd_bus_request_name.html
|
||||||
*/
|
*/
|
||||||
check(sd_bus_request_name_async(*o->bus,
|
r = sd_bus_request_name_async(*o->bus,
|
||||||
NULL,
|
NULL,
|
||||||
"org.freedesktop.ReconnectExample",
|
"org.freedesktop.ReconnectExample",
|
||||||
0,
|
0,
|
||||||
request_name_callback,
|
request_name_callback,
|
||||||
o));
|
o);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_bus_request_name_async()");
|
||||||
/* When D-Bus is disconnected this callback will be invoked, which will set up
|
/* When D-Bus is disconnected this callback will be invoked, which will set up
|
||||||
* the connection again. This needs to be asynchronous, as D-Bus might not yet
|
* the connection again. This needs to be asynchronous, as D-Bus might not yet
|
||||||
* be available.
|
* be available.
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_bus_match_signal_async.html
|
* https://www.freedesktop.org/software/systemd/man/sd_bus_match_signal_async.html
|
||||||
*/
|
*/
|
||||||
check(sd_bus_match_signal_async(*o->bus,
|
r = sd_bus_match_signal_async(*o->bus,
|
||||||
NULL,
|
NULL,
|
||||||
"org.freedesktop.DBus.Local",
|
"org.freedesktop.DBus.Local",
|
||||||
NULL,
|
NULL,
|
||||||
"org.freedesktop.DBus.Local",
|
"org.freedesktop.DBus.Local",
|
||||||
"Disconnected",
|
"Disconnected",
|
||||||
on_disconnect,
|
on_disconnect,
|
||||||
NULL,
|
NULL,
|
||||||
o));
|
o);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_bus_match_signal_async()");
|
||||||
/* Attach the bus object to the event loop so that calls and signals are
|
/* Attach the bus object to the event loop so that calls and signals are
|
||||||
* processed.
|
* processed.
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_bus_attach_event.html
|
* https://www.freedesktop.org/software/systemd/man/sd_bus_attach_event.html
|
||||||
*/
|
*/
|
||||||
check(sd_bus_attach_event(*o->bus, *o->event, 0));
|
r = sd_bus_attach_event(*o->bus, *o->event, 0);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_bus_attach_event()");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -199,28 +233,42 @@ int main(int argc, char **argv) {
|
|||||||
.bus = &bus,
|
.bus = &bus,
|
||||||
.event = &event,
|
.event = &event,
|
||||||
};
|
};
|
||||||
|
int r;
|
||||||
|
|
||||||
/* Create an event loop data structure, with default parameters.
|
/* Create an event loop data structure, with default parameters.
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_event_default.html
|
* https://www.freedesktop.org/software/systemd/man/sd_event_default.html
|
||||||
*/
|
*/
|
||||||
check(sd_event_default(&event));
|
r = sd_event_default(&event);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_event_default()");
|
||||||
|
|
||||||
/* By default the event loop will terminate when all sources have disappeared,
|
/* By default the event loop will terminate when all sources have disappeared,
|
||||||
* so we have to keep it 'occupied'. Register signal handling to do so.
|
* so we have to keep it 'occupied'. Register signal handling to do so.
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_event_add_signal.html
|
* https://www.freedesktop.org/software/systemd/man/sd_event_add_signal.html
|
||||||
*/
|
*/
|
||||||
check(sd_event_add_signal(event, NULL, SIGINT|SD_EVENT_SIGNAL_PROCMASK, NULL, NULL));
|
r = sd_event_add_signal(event, NULL, SIGINT|SD_EVENT_SIGNAL_PROCMASK, NULL, NULL);
|
||||||
check(sd_event_add_signal(event, NULL, SIGTERM|SD_EVENT_SIGNAL_PROCMASK, NULL, NULL));
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_event_add_signal(SIGINT)");
|
||||||
|
|
||||||
check(setup(&o));
|
r = sd_event_add_signal(event, NULL, SIGTERM|SD_EVENT_SIGNAL_PROCMASK, NULL, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_event_add_signal(SIGTERM)");
|
||||||
|
|
||||||
|
r = setup(&o);
|
||||||
|
if (r < 0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
/* Enter the main loop, it will exit only on sigint/sigterm.
|
/* Enter the main loop, it will exit only on sigint/sigterm.
|
||||||
* https://www.freedesktop.org/software/systemd/man/sd_event_loop.html
|
* https://www.freedesktop.org/software/systemd/man/sd_event_loop.html
|
||||||
*/
|
*/
|
||||||
check(sd_event_loop(event));
|
r = sd_event_loop(event);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_event_loop()");
|
||||||
|
|
||||||
/* https://www.freedesktop.org/software/systemd/man/sd_bus_release_name.html */
|
/* https://www.freedesktop.org/software/systemd/man/sd_bus_release_name.html */
|
||||||
check(sd_bus_release_name(bus, "org.freedesktop.ReconnectExample"));
|
r = sd_bus_release_name(bus, "org.freedesktop.ReconnectExample");
|
||||||
|
if (r < 0)
|
||||||
|
return log_error(r, "sd_bus_release_name()");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+52
-22
@@ -9,20 +9,14 @@
|
|||||||
|
|
||||||
#define _cleanup_(f) __attribute__((cleanup(f)))
|
#define _cleanup_(f) __attribute__((cleanup(f)))
|
||||||
|
|
||||||
#define check(x) ({ \
|
|
||||||
int r = (x); \
|
|
||||||
errno = r < 0 ? -r : 0; \
|
|
||||||
printf(#x ": %m\n"); \
|
|
||||||
if (r < 0) \
|
|
||||||
return EXIT_FAILURE; \
|
|
||||||
})
|
|
||||||
|
|
||||||
typedef struct object {
|
typedef struct object {
|
||||||
char *name;
|
char *name;
|
||||||
uint32_t number;
|
uint32_t number;
|
||||||
} object;
|
} object;
|
||||||
|
|
||||||
static int method(sd_bus_message *m, void *userdata, sd_bus_error *error) {
|
static int method(sd_bus_message *m, void *userdata, sd_bus_error *error) {
|
||||||
|
int r;
|
||||||
|
|
||||||
printf("Got called with userdata=%p\n", userdata);
|
printf("Got called with userdata=%p\n", userdata);
|
||||||
|
|
||||||
if (sd_bus_message_is_method_call(m,
|
if (sd_bus_message_is_method_call(m,
|
||||||
@@ -31,8 +25,17 @@ static int method(sd_bus_message *m, void *userdata, sd_bus_error *error) {
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
const char *string;
|
const char *string;
|
||||||
check(sd_bus_message_read(m, "s", &string));
|
r = sd_bus_message_read(m, "s", &string);
|
||||||
check(sd_bus_reply_method_return(m, "s", string));
|
if (r < 0) {
|
||||||
|
fprintf(stderr, "sd_bus_message_read() failed: %s\n", strerror(-r));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_bus_reply_method_return(m, "s", string);
|
||||||
|
if (r < 0) {
|
||||||
|
fprintf(stderr, "sd_bus_reply_method_return() failed: %s\n", strerror(-r));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -84,28 +87,55 @@ static const sd_bus_vtable vtable[] = {
|
|||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
sd_bus_default(&bus);
|
sd_bus_default(&bus);
|
||||||
|
|
||||||
object object = { .number = 666 };
|
object object = { .number = 666 };
|
||||||
check((object.name = strdup("name")) != NULL);
|
object.name = strdup("name");
|
||||||
|
if (!object.name) {
|
||||||
|
fprintf(stderr, "OOM\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
check(sd_bus_add_object_vtable(bus, NULL,
|
r = sd_bus_add_object_vtable(bus, NULL,
|
||||||
"/org/freedesktop/systemd/VtableExample",
|
"/org/freedesktop/systemd/VtableExample",
|
||||||
"org.freedesktop.systemd.VtableExample",
|
"org.freedesktop.systemd.VtableExample",
|
||||||
vtable,
|
vtable,
|
||||||
&object));
|
&object);
|
||||||
|
if (r < 0) {
|
||||||
|
fprintf(stderr, "sd_bus_add_object_vtable() failed: %s\n", strerror(-r));
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
check(sd_bus_request_name(bus,
|
r = sd_bus_request_name(bus,
|
||||||
"org.freedesktop.systemd.VtableExample",
|
"org.freedesktop.systemd.VtableExample",
|
||||||
0));
|
0);
|
||||||
|
if (r < 0) {
|
||||||
|
fprintf(stderr, "sd_bus_request_name() failed: %s\n", strerror(-r));
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
check(sd_bus_wait(bus, UINT64_MAX));
|
r = sd_bus_wait(bus, UINT64_MAX);
|
||||||
check(sd_bus_process(bus, NULL));
|
if (r < 0) {
|
||||||
|
fprintf(stderr, "sd_bus_wait() failed: %s\n", strerror(-r));
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_bus_process(bus, NULL);
|
||||||
|
if (r < 0) {
|
||||||
|
fprintf(stderr, "sd_bus_process() failed: %s\n", strerror(-r));
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_bus_release_name(bus, "org.freedesktop.systemd.VtableExample");
|
||||||
|
if (r < 0) {
|
||||||
|
fprintf(stderr, "sd_bus_release_name() failed: %s\n", strerror(-r));
|
||||||
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
check(sd_bus_release_name(bus, "org.freedesktop.systemd.VtableExample"));
|
|
||||||
free(object.name);
|
free(object.name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user