man/examples: use strerror() instead of %m

This commit is contained in:
Yu Watanabe 2024-04-03 03:40:05 +09:00
parent 06d0dcc009
commit e84f70e16d
11 changed files with 197 additions and 115 deletions

View File

@ -11,8 +11,7 @@ int main(int argc, char *argv[]) {
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
if (r < 0) {
errno = -r;
fprintf(stderr, "Failed to open journal: %m\n");
fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
return 1;
}
SD_JOURNAL_FOREACH_FIELD(j, field)

View File

@ -7,10 +7,10 @@
int main(int argc, char *argv[]) {
int r;
sd_journal *j;
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
if (r < 0) {
errno = -r;
fprintf(stderr, "Failed to open journal: %m\n");
fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
return 1;
}
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);
if (r < 0) {
errno = -r;
fprintf(stderr, "Failed to read message field: %m\n");
fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
continue;
}

View File

@ -12,14 +12,12 @@ int main(int argc, char *argv[]) {
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
if (r < 0) {
errno = -r;
fprintf(stderr, "Failed to open journal: %m\n");
fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
return 1;
}
r = sd_journal_query_unique(j, "_SYSTEMD_UNIT");
if (r < 0) {
errno = -r;
fprintf(stderr, "Failed to query journal: %m\n");
fprintf(stderr, "Failed to query journal: %s\n", strerror(-r));
return 1;
}
SD_JOURNAL_FOREACH_UNIQUE(j, d, l)

View File

@ -7,39 +7,38 @@
int main(int argc, char *argv[]) {
int r;
sd_journal *j;
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
if (r < 0) {
errno = -r;
fprintf(stderr, "Failed to open journal: %m\n");
fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
return 1;
}
for (;;) {
const void *d;
size_t l;
r = sd_journal_next(j);
if (r < 0) {
errno = -r;
fprintf(stderr, "Failed to iterate to next entry: %m\n");
fprintf(stderr, "Failed to iterate to next entry: %s\n", strerror(-r));
break;
}
if (r == 0) {
/* Reached the end, let's wait for changes, and try again */
r = sd_journal_wait(j, (uint64_t) -1);
if (r < 0) {
errno = -r;
fprintf(stderr, "Failed to wait for changes: %m\n");
fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
break;
}
continue;
}
r = sd_journal_get_data(j, "MESSAGE", &d, &l);
if (r < 0) {
errno = -r;
fprintf(stderr, "Failed to read message field: %m\n");
fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
continue;
}
printf("%.*s\n", (int) l, (const char*) d);
}
sd_journal_close(j);
return 0;
}

View File

@ -10,15 +10,16 @@
int main(int argc, char *argv[]) {
int fd;
FILE *log;
fd = sd_journal_stream_fd("test", LOG_INFO, 1);
if (fd < 0) {
errno = -fd;
fprintf(stderr, "Failed to create stream fd: %m\n");
fprintf(stderr, "Failed to create stream fd: %s\n", strerror(-fd));
return 1;
}
log = fdopen(fd, "w");
if (!log) {
fprintf(stderr, "Failed to create file object: %m\n");
fprintf(stderr, "Failed to create file object: %s\n", strerror(errno));
close(fd);
return 1;
}

View File

@ -43,13 +43,10 @@
#define _cleanup_(f) __attribute__((cleanup(f)))
#define check(log_level, x) ({ \
int _r = (x); \
errno = _r < 0 ? -_r : 0; \
sd_journal_print((log_level), #x ": %m"); \
if (_r < 0) \
return EXIT_FAILURE; \
})
static int log_error(int log_level, int error, const char *str) {
sd_journal_print(log_level, "%s failed: %s", str, strerror(-error));
return error;
}
typedef enum LogTarget {
LOG_TARGET_JOURNAL,
@ -193,6 +190,7 @@ int main(int argc, char **argv) {
.log_target = LOG_TARGET_JOURNAL,
.syslog_identifier = "example",
};
int r;
/* https://man7.org/linux/man-pages/man3/setlogmask.3.html
* 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.
* 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
* path and public interface name.
* https://www.freedesktop.org/software/systemd/man/sd_bus_add_object.html
* https://dbus.freedesktop.org/doc/dbus-tutorial.html
*/
check(o.log_level, sd_bus_add_object_vtable(bus, NULL,
"/org/freedesktop/LogControl1",
"org.freedesktop.LogControl1",
vtable,
&o));
r = sd_bus_add_object_vtable(bus, NULL,
"/org/freedesktop/LogControl1",
"org.freedesktop.LogControl1",
vtable,
&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
* one, so that clients know whom to call.
* 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 (;;) {
/* 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
*/
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
*/
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;
}

View File

@ -21,8 +21,7 @@
#define MEMBER "GetUnitByPID"
static int log_error(int error, const char *message) {
errno = -error;
fprintf(stderr, "%s: %m\n", message);
fprintf(stderr, "%s: %s\n", message, strerror(-error));
return error;
}

View File

@ -21,8 +21,7 @@
#define MEMBER "GetUnitByPID"
static int log_error(int error, const char *message) {
errno = -error;
fprintf(stderr, "%s: %m\n", message);
fprintf(stderr, "%s: %s\n", message, strerror(-error));
return error;
}

View File

@ -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
* 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));
}

View File

@ -42,13 +42,10 @@
#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; \
})
static int log_error(int r, const char *str) {
fprintf(stderr, "%s failed: %s\n", str, strerror(-r));
return r;
}
typedef struct object {
const char *example;
@ -90,13 +87,24 @@ static const sd_bus_vtable vtable[] = {
static int setup(object *o);
static int on_disconnect(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
check(setup((object *)userdata));
return 0;
int r;
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
* service name fails */
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))
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))
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;
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;
}
static int setup(object *o) {
int r;
/* If we are reconnecting, then the bus object needs to be closed, detached
* 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_close_unref.html
*/
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);
}
@ -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_start.html
*/
check(sd_bus_new(o->bus));
check(sd_bus_set_address(*o->bus, "unix:path=/run/dbus/system_bus_socket"));
check(sd_bus_set_bus_client(*o->bus, 1));
check(sd_bus_negotiate_creds(*o->bus, 1, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS));
check(sd_bus_set_watch_bind(*o->bus, 1));
check(sd_bus_start(*o->bus));
r = sd_bus_new(o->bus);
if (r < 0)
return log_error(r, "sd_bus_new()");
r = sd_bus_set_address(*o->bus, "unix:path=/run/dbus/system_bus_socket");
if (r < 0)
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
* path and public interface name.
* https://www.freedesktop.org/software/systemd/man/sd_bus_add_object.html
* https://dbus.freedesktop.org/doc/dbus-tutorial.html
*/
check(sd_bus_add_object_vtable(*o->bus,
NULL,
"/org/freedesktop/ReconnectExample",
"org.freedesktop.ReconnectExample",
vtable,
o));
r = sd_bus_add_object_vtable(*o->bus,
NULL,
"/org/freedesktop/ReconnectExample",
"org.freedesktop.ReconnectExample",
vtable,
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
* 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
* whether the error is expected or not, in case it fails.
* https://www.freedesktop.org/software/systemd/man/sd_bus_request_name.html
*/
check(sd_bus_request_name_async(*o->bus,
NULL,
"org.freedesktop.ReconnectExample",
0,
request_name_callback,
o));
r = sd_bus_request_name_async(*o->bus,
NULL,
"org.freedesktop.ReconnectExample",
0,
request_name_callback,
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
* the connection again. This needs to be asynchronous, as D-Bus might not yet
* be available.
* https://www.freedesktop.org/software/systemd/man/sd_bus_match_signal_async.html
*/
check(sd_bus_match_signal_async(*o->bus,
NULL,
"org.freedesktop.DBus.Local",
NULL,
"org.freedesktop.DBus.Local",
"Disconnected",
on_disconnect,
NULL,
o));
r = sd_bus_match_signal_async(*o->bus,
NULL,
"org.freedesktop.DBus.Local",
NULL,
"org.freedesktop.DBus.Local",
"Disconnected",
on_disconnect,
NULL,
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
* processed.
* 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;
}
@ -199,28 +233,42 @@ int main(int argc, char **argv) {
.bus = &bus,
.event = &event,
};
int r;
/* Create an event loop data structure, with default parameters.
* 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,
* 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
*/
check(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));
r = sd_event_add_signal(event, NULL, SIGINT|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.
* 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 */
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;
}

View File

@ -9,20 +9,14 @@
#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 {
char *name;
uint32_t number;
} object;
static int method(sd_bus_message *m, void *userdata, sd_bus_error *error) {
int r;
printf("Got called with userdata=%p\n", userdata);
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;
const char *string;
check(sd_bus_message_read(m, "s", &string));
check(sd_bus_reply_method_return(m, "s", string));
r = sd_bus_message_read(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;
}
@ -84,28 +87,55 @@ static const sd_bus_vtable vtable[] = {
int main(int argc, char **argv) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
int r;
sd_bus_default(&bus);
object object = { .number = 666 };
check((object.name = strdup("name")) != NULL);
check(sd_bus_add_object_vtable(bus, NULL,
"/org/freedesktop/systemd/VtableExample",
"org.freedesktop.systemd.VtableExample",
vtable,
&object));
check(sd_bus_request_name(bus,
"org.freedesktop.systemd.VtableExample",
0));
for (;;) {
check(sd_bus_wait(bus, UINT64_MAX));
check(sd_bus_process(bus, NULL));
object.name = strdup("name");
if (!object.name) {
fprintf(stderr, "OOM\n");
return EXIT_FAILURE;
}
r = sd_bus_add_object_vtable(bus, NULL,
"/org/freedesktop/systemd/VtableExample",
"org.freedesktop.systemd.VtableExample",
vtable,
&object);
if (r < 0) {
fprintf(stderr, "sd_bus_add_object_vtable() failed: %s\n", strerror(-r));
return EXIT_FAILURE;
}
r = sd_bus_request_name(bus,
"org.freedesktop.systemd.VtableExample",
0);
if (r < 0) {
fprintf(stderr, "sd_bus_request_name() failed: %s\n", strerror(-r));
return EXIT_FAILURE;
}
for (;;) {
r = sd_bus_wait(bus, UINT64_MAX);
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);
return 0;