static int server(sd_bus *bus) { int r; bool client1_gone = false, client2_gone = false; while (!client1_gone || !client2_gone) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL; pid_t pid = 0; const char *label = NULL; r = sd_bus_process(bus, &m); if (r < 0) { log_error_errno(r, "Failed to process requests: %m"); goto fail; } if (r == 0) { r = sd_bus_wait(bus, (uint64_t) -1); if (r < 0) { log_error_errno(r, "Failed to wait: %m"); goto fail; } continue; } if (!m) continue; sd_bus_creds_get_pid(sd_bus_message_get_creds(m), &pid); sd_bus_creds_get_selinux_context(sd_bus_message_get_creds(m), &label); log_info("Got message! member=%s pid="PID_FMT" label=%s", strna(sd_bus_message_get_member(m)), pid, strna(label)); /* bus_message_dump(m); */ /* sd_bus_message_rewind(m, true); */ if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) { const char *hello; _cleanup_free_ char *lowercase = NULL; r = sd_bus_message_read(m, "s", &hello); if (r < 0) { log_error_errno(r, "Failed to get parameter: %m"); goto fail; } lowercase = strdup(hello); if (!lowercase) { r = log_oom(); goto fail; } ascii_strlower(lowercase); r = sd_bus_reply_method_return(m, "s", lowercase); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) { r = sd_bus_reply_method_return(m, NULL); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } client1_gone = true; } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient2")) { r = sd_bus_reply_method_return(m, NULL); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } client2_gone = true; } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Slow")) { sleep(1); r = sd_bus_reply_method_return(m, NULL); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "FileDescriptor")) { int fd; static const char x = 'X'; r = sd_bus_message_read(m, "h", &fd); if (r < 0) { log_error_errno(r, "Failed to get parameter: %m"); goto fail; } log_info("Received fd=%d", fd); if (write(fd, &x, 1) < 0) { log_error_errno(errno, "Failed to write to fd: %m"); safe_close(fd); goto fail; } r = sd_bus_reply_method_return(m, NULL); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } } else if (sd_bus_message_is_method_call(m, NULL, NULL)) { r = sd_bus_reply_method_error( m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method.")); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } } } r = 0; fail: if (bus) { sd_bus_flush(bus); sd_bus_unref(bus); } return r; }
static void *server(void *p) { struct context *c = p; sd_bus *bus = NULL; sd_id128_t id; bool quit = false; int r; assert_se(sd_id128_randomize(&id) >= 0); assert_se(sd_bus_new(&bus) >= 0); assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0); assert_se(sd_bus_set_server(bus, 1, id) >= 0); assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0); assert_se(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0); assert_se(sd_bus_start(bus) >= 0); while (!quit) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; r = sd_bus_process(bus, &m); if (r < 0) { log_error("Failed to process requests: %s", strerror(-r)); goto fail; } if (r == 0) { r = sd_bus_wait(bus, (uint64_t) -1); if (r < 0) { log_error("Failed to wait: %s", strerror(-r)); goto fail; } continue; } if (!m) continue; log_info("Got message! member=%s", strna(sd_bus_message_get_member(m))); if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Exit")) { assert_se((sd_bus_can_send(bus, 'h') >= 1) == (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds)); r = sd_bus_message_new_method_return(m, &reply); if (r < 0) { log_error("Failed to allocate return: %s", strerror(-r)); goto fail; } quit = true; } else if (sd_bus_message_is_method_call(m, NULL, NULL)) { r = sd_bus_message_new_method_error( m, &reply, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method.")); if (r < 0) { log_error("Failed to allocate return: %s", strerror(-r)); goto fail; } } if (reply) { r = sd_bus_send(bus, reply, NULL); if (r < 0) { log_error("Failed to send reply: %s", strerror(-r)); goto fail; } } } r = 0; fail: if (bus) { sd_bus_flush(bus); sd_bus_unref(bus); } return INT_TO_PTR(r); }
int main(int argc, char *argv[]) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL, second = SD_BUS_ERROR_NULL; const sd_bus_error const_error = SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_FILE_EXISTS, "const error"); const sd_bus_error temporarily_const_error = { .name = SD_BUS_ERROR_ACCESS_DENIED, .message = "oh! no", ._need_free = -1 }; assert_se(!sd_bus_error_is_set(&error)); assert_se(sd_bus_error_set(&error, SD_BUS_ERROR_NOT_SUPPORTED, "xxx") == -ENOTSUP); assert_se(streq(error.name, SD_BUS_ERROR_NOT_SUPPORTED)); assert_se(streq(error.message, "xxx")); assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_NOT_SUPPORTED)); assert_se(sd_bus_error_get_errno(&error) == ENOTSUP); assert_se(sd_bus_error_is_set(&error)); sd_bus_error_free(&error); assert_se(!sd_bus_error_is_set(&error)); assert_se(sd_bus_error_setf(&error, SD_BUS_ERROR_FILE_NOT_FOUND, "yyy %i", -1) == -ENOENT); assert_se(streq(error.name, SD_BUS_ERROR_FILE_NOT_FOUND)); assert_se(streq(error.message, "yyy -1")); assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_FILE_NOT_FOUND)); assert_se(sd_bus_error_get_errno(&error) == ENOENT); assert_se(sd_bus_error_is_set(&error)); assert_se(!sd_bus_error_is_set(&second)); assert_se(second._need_free == 0); assert_se(error._need_free > 0); assert_se(sd_bus_error_copy(&second, &error) == -ENOENT); assert_se(second._need_free > 0); assert_se(streq(error.name, second.name)); assert_se(streq(error.message, second.message)); assert_se(sd_bus_error_get_errno(&second) == ENOENT); assert_se(sd_bus_error_has_name(&second, SD_BUS_ERROR_FILE_NOT_FOUND)); assert_se(sd_bus_error_is_set(&second)); sd_bus_error_free(&error); sd_bus_error_free(&second); assert_se(!sd_bus_error_is_set(&second)); assert_se(const_error._need_free == 0); assert_se(sd_bus_error_copy(&second, &const_error) == -EEXIST); assert_se(second._need_free == 0); assert_se(streq(const_error.name, second.name)); assert_se(streq(const_error.message, second.message)); assert_se(sd_bus_error_get_errno(&second) == EEXIST); assert_se(sd_bus_error_has_name(&second, SD_BUS_ERROR_FILE_EXISTS)); assert_se(sd_bus_error_is_set(&second)); sd_bus_error_free(&second); assert_se(!sd_bus_error_is_set(&second)); assert_se(temporarily_const_error._need_free < 0); assert_se(sd_bus_error_copy(&second, &temporarily_const_error) == -EACCES); assert_se(second._need_free > 0); assert_se(streq(temporarily_const_error.name, second.name)); assert_se(streq(temporarily_const_error.message, second.message)); assert_se(sd_bus_error_get_errno(&second) == EACCES); assert_se(sd_bus_error_has_name(&second, SD_BUS_ERROR_ACCESS_DENIED)); assert_se(sd_bus_error_is_set(&second)); assert_se(!sd_bus_error_is_set(&error)); assert_se(sd_bus_error_set_const(&error, "System.Error.EUCLEAN", "Hallo") == -EUCLEAN); assert_se(streq(error.name, "System.Error.EUCLEAN")); assert_se(streq(error.message, "Hallo")); assert_se(sd_bus_error_has_name(&error, "System.Error.EUCLEAN")); assert_se(sd_bus_error_get_errno(&error) == EUCLEAN); assert_se(sd_bus_error_is_set(&error)); sd_bus_error_free(&error); assert_se(!sd_bus_error_is_set(&error)); assert_se(sd_bus_error_set_errno(&error, EBUSY) == -EBUSY); assert_se(streq(error.name, "System.Error.EBUSY")); assert_se(streq(error.message, strerror(EBUSY))); assert_se(sd_bus_error_has_name(&error, "System.Error.EBUSY")); assert_se(sd_bus_error_get_errno(&error) == EBUSY); assert_se(sd_bus_error_is_set(&error)); sd_bus_error_free(&error); assert_se(!sd_bus_error_is_set(&error)); assert_se(sd_bus_error_set_errnof(&error, EIO, "Waldi %c", 'X') == -EIO); assert_se(streq(error.name, SD_BUS_ERROR_IO_ERROR)); assert_se(streq(error.message, "Waldi X")); assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_IO_ERROR)); assert_se(sd_bus_error_get_errno(&error) == EIO); assert_se(sd_bus_error_is_set(&error)); return 0; }
static void test_error(void) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL, second = SD_BUS_ERROR_NULL; const sd_bus_error const_error = SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_FILE_EXISTS, "const error"); const sd_bus_error temporarily_const_error = { .name = SD_BUS_ERROR_ACCESS_DENIED, .message = "oh! no", ._need_free = -1 }; assert_se(!sd_bus_error_is_set(&error)); assert_se(sd_bus_error_set(&error, SD_BUS_ERROR_NOT_SUPPORTED, "xxx") == -EOPNOTSUPP); assert_se(streq(error.name, SD_BUS_ERROR_NOT_SUPPORTED)); assert_se(streq(error.message, "xxx")); assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_NOT_SUPPORTED)); assert_se(sd_bus_error_get_errno(&error) == EOPNOTSUPP); assert_se(sd_bus_error_is_set(&error)); sd_bus_error_free(&error); assert_se(!sd_bus_error_is_set(&error)); assert_se(sd_bus_error_setf(&error, SD_BUS_ERROR_FILE_NOT_FOUND, "yyy %i", -1) == -ENOENT); assert_se(streq(error.name, SD_BUS_ERROR_FILE_NOT_FOUND)); assert_se(streq(error.message, "yyy -1")); assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_FILE_NOT_FOUND)); assert_se(sd_bus_error_get_errno(&error) == ENOENT); assert_se(sd_bus_error_is_set(&error)); assert_se(!sd_bus_error_is_set(&second)); assert_se(second._need_free == 0); assert_se(error._need_free > 0); assert_se(sd_bus_error_copy(&second, &error) == -ENOENT); assert_se(second._need_free > 0); assert_se(streq(error.name, second.name)); assert_se(streq(error.message, second.message)); assert_se(sd_bus_error_get_errno(&second) == ENOENT); assert_se(sd_bus_error_has_name(&second, SD_BUS_ERROR_FILE_NOT_FOUND)); assert_se(sd_bus_error_is_set(&second)); sd_bus_error_free(&error); sd_bus_error_free(&second); assert_se(!sd_bus_error_is_set(&second)); assert_se(const_error._need_free == 0); assert_se(sd_bus_error_copy(&second, &const_error) == -EEXIST); assert_se(second._need_free == 0); assert_se(streq(const_error.name, second.name)); assert_se(streq(const_error.message, second.message)); assert_se(sd_bus_error_get_errno(&second) == EEXIST); assert_se(sd_bus_error_has_name(&second, SD_BUS_ERROR_FILE_EXISTS)); assert_se(sd_bus_error_is_set(&second)); sd_bus_error_free(&second); assert_se(!sd_bus_error_is_set(&second)); assert_se(temporarily_const_error._need_free < 0); assert_se(sd_bus_error_copy(&second, &temporarily_const_error) == -EACCES); assert_se(second._need_free > 0); assert_se(streq(temporarily_const_error.name, second.name)); assert_se(streq(temporarily_const_error.message, second.message)); assert_se(sd_bus_error_get_errno(&second) == EACCES); assert_se(sd_bus_error_has_name(&second, SD_BUS_ERROR_ACCESS_DENIED)); assert_se(sd_bus_error_is_set(&second)); assert_se(!sd_bus_error_is_set(&error)); assert_se(sd_bus_error_set_const(&error, "System.Error.EUCLEAN", "Hallo") == -EUCLEAN); assert_se(streq(error.name, "System.Error.EUCLEAN")); assert_se(streq(error.message, "Hallo")); assert_se(sd_bus_error_has_name(&error, "System.Error.EUCLEAN")); assert_se(sd_bus_error_get_errno(&error) == EUCLEAN); assert_se(sd_bus_error_is_set(&error)); sd_bus_error_free(&error); assert_se(!sd_bus_error_is_set(&error)); assert_se(sd_bus_error_set_errno(&error, EBUSY) == -EBUSY); assert_se(streq(error.name, "System.Error.EBUSY")); assert_se(streq(error.message, strerror(EBUSY))); assert_se(sd_bus_error_has_name(&error, "System.Error.EBUSY")); assert_se(sd_bus_error_get_errno(&error) == EBUSY); assert_se(sd_bus_error_is_set(&error)); sd_bus_error_free(&error); assert_se(!sd_bus_error_is_set(&error)); assert_se(sd_bus_error_set_errnof(&error, EIO, "Waldi %c", 'X') == -EIO); assert_se(streq(error.name, SD_BUS_ERROR_IO_ERROR)); assert_se(streq(error.message, "Waldi X")); assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_IO_ERROR)); assert_se(sd_bus_error_get_errno(&error) == EIO); assert_se(sd_bus_error_is_set(&error)); } extern const sd_bus_error_map __start_BUS_ERROR_MAP[]; extern const sd_bus_error_map __stop_BUS_ERROR_MAP[]; static void dump_mapping_table(void) { const sd_bus_error_map *m; printf("----- errno mappings ------\n"); m = __start_BUS_ERROR_MAP; while (m < __stop_BUS_ERROR_MAP) { if (m->code == BUS_ERROR_MAP_END_MARKER) { m = ALIGN8_PTR(m+1); continue; } printf("%s -> %i/%s\n", strna(m->name), m->code, strna(errno_to_name(m->code))); m ++; } printf("---------------------------\n"); } static void test_errno_mapping_standard(void) { assert_se(sd_bus_error_set(NULL, "System.Error.EUCLEAN", NULL) == -EUCLEAN); assert_se(sd_bus_error_set(NULL, "System.Error.EBUSY", NULL) == -EBUSY); assert_se(sd_bus_error_set(NULL, "System.Error.EINVAL", NULL) == -EINVAL); assert_se(sd_bus_error_set(NULL, "System.Error.WHATSIT", NULL) == -EIO); }