mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
sd-bus: rework ELF error mapping table magic
The ELF magic cannot work for consumers of our shard library, since they are in a different module. Hence make all the ELF magic private, and instead introduce a public function to register additional static mapping table.
This commit is contained in:
parent
8b5e2af108
commit
5f86c1f4c4
@ -32,61 +32,54 @@
|
||||
#include "sd-bus.h"
|
||||
#include "bus-error.h"
|
||||
|
||||
#define BUS_ERROR_OOM SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_MEMORY, "Out of memory")
|
||||
#define BUS_ERROR_FAILED SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_FAILED, "Operation failed")
|
||||
|
||||
SD_BUS_ERROR_MAPPING(sd_bus_standard) = {
|
||||
{"org.freedesktop.DBus.Error.Failed", EACCES},
|
||||
{"org.freedesktop.DBus.Error.NoMemory", ENOMEM},
|
||||
{"org.freedesktop.DBus.Error.ServiceUnknown", EHOSTUNREACH},
|
||||
{"org.freedesktop.DBus.Error.NameHasNoOwner", ENXIO},
|
||||
{"org.freedesktop.DBus.Error.NoReply", ETIMEDOUT},
|
||||
{"org.freedesktop.DBus.Error.IOError", EIO},
|
||||
{"org.freedesktop.DBus.Error.BadAddress", EADDRNOTAVAIL},
|
||||
{"org.freedesktop.DBus.Error.NotSupported", ENOTSUP},
|
||||
{"org.freedesktop.DBus.Error.LimitsExceeded", ENOBUFS},
|
||||
{"org.freedesktop.DBus.Error.AccessDenied", EACCES},
|
||||
{"org.freedesktop.DBus.Error.AuthFailed", EACCES},
|
||||
{"org.freedesktop.DBus.Error.InteractiveAuthorizationRequired", EACCES},
|
||||
{"org.freedesktop.DBus.Error.NoServer", EHOSTDOWN},
|
||||
{"org.freedesktop.DBus.Error.Timeout", ETIMEDOUT},
|
||||
{"org.freedesktop.DBus.Error.NoNetwork", ENONET},
|
||||
{"org.freedesktop.DBus.Error.AddressInUse", EADDRINUSE},
|
||||
{"org.freedesktop.DBus.Error.Disconnected", ECONNRESET},
|
||||
{"org.freedesktop.DBus.Error.InvalidArgs", EINVAL},
|
||||
{"org.freedesktop.DBus.Error.FileNotFound", ENOENT},
|
||||
{"org.freedesktop.DBus.Error.FileExists", EEXIST},
|
||||
{"org.freedesktop.DBus.Error.UnknownMethod", EBADR},
|
||||
{"org.freedesktop.DBus.Error.UnknownObject", EBADR},
|
||||
{"org.freedesktop.DBus.Error.UnknownInterface", EBADR},
|
||||
{"org.freedesktop.DBus.Error.UnknownProperty", EBADR},
|
||||
{"org.freedesktop.DBus.Error.PropertyReadOnly", EROFS},
|
||||
{"org.freedesktop.DBus.Error.UnixProcessIdUnknown", ESRCH},
|
||||
{"org.freedesktop.DBus.Error.InvalidSignature", EINVAL},
|
||||
{"org.freedesktop.DBus.Error.InconsistentMessage", EBADMSG},
|
||||
|
||||
{"org.freedesktop.DBus.Error.TimedOut", ETIMEDOUT},
|
||||
{"org.freedesktop.DBus.Error.MatchRuleInvalid", EINVAL},
|
||||
{"org.freedesktop.DBus.Error.InvalidFileContent", EINVAL},
|
||||
{"org.freedesktop.DBus.Error.MatchRuleNotFound", ENOENT},
|
||||
{"org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown", ESRCH},
|
||||
{"org.freedesktop.DBus.Error.ObjectPathInUse", EBUSY},
|
||||
BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map standard_errors[] = {
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.Failed", EACCES),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.NoMemory", ENOMEM),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.ServiceUnknown", EHOSTUNREACH),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.NameHasNoOwner", ENXIO),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.NoReply", ETIMEDOUT),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.IOError", EIO),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.BadAddress", EADDRNOTAVAIL),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.NotSupported", ENOTSUP),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.LimitsExceeded", ENOBUFS),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.AccessDenied", EACCES),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.AuthFailed", EACCES),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.InteractiveAuthorizationRequired", EACCES),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.NoServer", EHOSTDOWN),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.Timeout", ETIMEDOUT),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.NoNetwork", ENONET),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.AddressInUse", EADDRINUSE),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.Disconnected", ECONNRESET),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.InvalidArgs", EINVAL),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.FileNotFound", ENOENT),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.FileExists", EEXIST),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.UnknownMethod", EBADR),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.UnknownObject", EBADR),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.UnknownInterface", EBADR),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.UnknownProperty", EBADR),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.PropertyReadOnly", EROFS),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.UnixProcessIdUnknown", ESRCH),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.InvalidSignature", EINVAL),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.InconsistentMessage", EBADMSG),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.TimedOut", ETIMEDOUT),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.MatchRuleInvalid", EINVAL),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.InvalidFileContent", EINVAL),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.MatchRuleNotFound", ENOENT),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown", ESRCH),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.ObjectPathInUse", EBUSY),
|
||||
SD_BUS_ERROR_MAP_END
|
||||
};
|
||||
|
||||
extern const sd_bus_name_error_mapping __start_sd_bus_errnomap[];
|
||||
extern const sd_bus_name_error_mapping __stop_sd_bus_errnomap[];
|
||||
/* GCC maps this magically to the beginning and end of the BUS_ERROR_MAP section */
|
||||
extern const sd_bus_error_map __start_BUS_ERROR_MAP[];
|
||||
extern const sd_bus_error_map __stop_BUS_ERROR_MAP[];
|
||||
|
||||
static int bus_error_mapping_lookup(const char *name, size_t len) {
|
||||
const sd_bus_name_error_mapping *m;
|
||||
|
||||
for (m = __start_sd_bus_errnomap; m < __stop_sd_bus_errnomap; m++)
|
||||
if (m->name && strneq(m->name, name, len))
|
||||
return m->code;
|
||||
|
||||
return EIO;
|
||||
}
|
||||
/* Additional maps registered with sd_bus_error_add_map() are in this
|
||||
* NULL terminated array */
|
||||
static const sd_bus_error_map **additional_error_maps = NULL;
|
||||
|
||||
static int bus_error_name_to_errno(const char *name) {
|
||||
const sd_bus_error_map **map, *m;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
@ -102,7 +95,39 @@ static int bus_error_name_to_errno(const char *name) {
|
||||
return r;
|
||||
}
|
||||
|
||||
return bus_error_mapping_lookup(name, strlen(name));
|
||||
if (additional_error_maps) {
|
||||
for (map = additional_error_maps; *map; map++) {
|
||||
for (m = *map;; m++) {
|
||||
/* For additional error maps the end marker is actually the end marker */
|
||||
if (m->code == BUS_ERROR_MAP_END_MARKER)
|
||||
break;
|
||||
|
||||
if (streq(m->name, name))
|
||||
return m->code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = __start_BUS_ERROR_MAP;
|
||||
while (m < __stop_BUS_ERROR_MAP) {
|
||||
/* For magic ELF error maps, the end marker might
|
||||
* appear in the middle of things, since multiple maps
|
||||
* might appear in the same section. Hence, let's skip
|
||||
* over it, but realign the pointer to the netx 8byte
|
||||
* boundary, which is the selected alignment for the
|
||||
* arrays. */
|
||||
if (m->code == BUS_ERROR_MAP_END_MARKER) {
|
||||
m = ALIGN8_PTR(m+1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (streq(m->name, name))
|
||||
return m->code;
|
||||
|
||||
m++;
|
||||
}
|
||||
|
||||
return EIO;
|
||||
}
|
||||
|
||||
static sd_bus_error errno_to_bus_error_const(int error) {
|
||||
@ -552,3 +577,31 @@ const char *bus_error_message(const sd_bus_error *e, int error) {
|
||||
|
||||
return strerror(error);
|
||||
}
|
||||
|
||||
_public_ int sd_bus_error_add_map(const sd_bus_error_map *map) {
|
||||
const sd_bus_error_map **maps = NULL;
|
||||
unsigned n = 0;
|
||||
|
||||
assert_return(map, -EINVAL);
|
||||
|
||||
if (additional_error_maps) {
|
||||
for (;; n++) {
|
||||
if (additional_error_maps[n] == NULL)
|
||||
break;
|
||||
|
||||
if (additional_error_maps[n] == map)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
maps = realloc_multiply(additional_error_maps, sizeof(struct sd_bus_error_map*), n + 2);
|
||||
if (!maps)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
maps[n] = map;
|
||||
maps[n+1] = NULL;
|
||||
|
||||
additional_error_maps = maps;
|
||||
return 1;
|
||||
}
|
||||
|
@ -26,15 +26,40 @@
|
||||
#include "sd-bus.h"
|
||||
#include "macro.h"
|
||||
|
||||
struct name_error_mapping {
|
||||
const char* name;
|
||||
int code;
|
||||
};
|
||||
typedef struct name_error_mapping name_error_mapping;
|
||||
|
||||
bool bus_error_is_dirty(sd_bus_error *e);
|
||||
|
||||
const char *bus_error_message(const sd_bus_error *e, int error);
|
||||
|
||||
int bus_error_setfv(sd_bus_error *e, const char *name, const char *format, va_list ap) _printf_(3,0);
|
||||
int bus_error_set_errnofv(sd_bus_error *e, int error, const char *format, va_list ap) _printf_(3,0);
|
||||
|
||||
#define BUS_ERROR_OOM SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_MEMORY, "Out of memory")
|
||||
#define BUS_ERROR_FAILED SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_FAILED, "Operation failed")
|
||||
|
||||
/*
|
||||
* There are two ways to register error maps with the error translation
|
||||
* logic: by using BUS_ERROR_MAP_ELF_REGISTER, which however only
|
||||
* works when linked into the same ELF module, or via
|
||||
* sd_bus_error_add_map() which is the official, external API, that
|
||||
* works from any module.
|
||||
*
|
||||
* Note that BUS_ERROR_MAP_ELF_REGISTER has to be used as decorator in
|
||||
* the bus error table, and BUS_ERROR_MAP_ELF_USE has to be used at
|
||||
* least once per compilation unit (i.e. per library), to ensure that
|
||||
* the error map is really added to the final binary.
|
||||
*/
|
||||
|
||||
#define BUS_ERROR_MAP_ELF_REGISTER \
|
||||
__attribute__ ((__section__("BUS_ERROR_MAP"))) \
|
||||
__attribute__ ((__used__)) \
|
||||
__attribute__ ((aligned(8)))
|
||||
|
||||
#define BUS_ERROR_MAP_ELF_USE(errors) \
|
||||
extern const sd_bus_error_map errors[]; \
|
||||
__attribute__ ((used)) static const sd_bus_error_map * CONCATENATE(errors ## _copy_, __COUNTER__) = errors;
|
||||
|
||||
/* We use something exotic as end marker, to ensure people build the
|
||||
* maps using the macsd-ros. */
|
||||
#define BUS_ERROR_MAP_END_MARKER -'x'
|
||||
|
||||
BUS_ERROR_MAP_ELF_USE(standard_errors);
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "sd-bus.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-util.h"
|
||||
#include "errno-list.h"
|
||||
#include "bus-errors.h"
|
||||
|
||||
static void test_error(void) {
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL, second = SD_BUS_ERROR_NULL;
|
||||
@ -111,15 +113,24 @@ static void test_error(void) {
|
||||
assert_se(sd_bus_error_is_set(&error));
|
||||
}
|
||||
|
||||
extern const sd_bus_name_error_mapping __start_sd_bus_errnomap[];
|
||||
extern const sd_bus_name_error_mapping __stop_sd_bus_errnomap[];
|
||||
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_name_error_mapping *m;
|
||||
const sd_bus_error_map *m;
|
||||
|
||||
printf("----- errno mappings ------\n");
|
||||
for (m = __start_sd_bus_errnomap; m < __stop_sd_bus_errnomap; m++)
|
||||
printf("%s -> %d\n", m->name, m->code);
|
||||
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");
|
||||
}
|
||||
|
||||
@ -130,15 +141,54 @@ static void test_errno_mapping_standard(void) {
|
||||
assert_se(sd_bus_error_set(NULL, "System.Error.WHATSIT", NULL) == -EIO);
|
||||
}
|
||||
|
||||
SD_BUS_ERROR_MAPPING(test) = {
|
||||
{"org.freedesktop.custom-dbus-error", 5},
|
||||
{"org.freedesktop.custom-dbus-error-2", 52},
|
||||
BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map test_errors[] = {
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error", 5),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-2", 52),
|
||||
SD_BUS_ERROR_MAP_END
|
||||
};
|
||||
|
||||
BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map test_errors2[] = {
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-3", 33),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-4", 44),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-33", 333),
|
||||
SD_BUS_ERROR_MAP_END
|
||||
};
|
||||
|
||||
static const sd_bus_error_map test_errors3[] = {
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-88", 888),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-99", 999),
|
||||
SD_BUS_ERROR_MAP_END
|
||||
};
|
||||
|
||||
static const sd_bus_error_map test_errors4[] = {
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-77", 777),
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-78", 778),
|
||||
SD_BUS_ERROR_MAP_END
|
||||
};
|
||||
|
||||
static void test_errno_mapping_custom(void) {
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error", NULL) == -5);
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-2", NULL) == -52);
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-x", NULL) == -EIO);
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-33", NULL) == -333);
|
||||
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-88", NULL) == -EIO);
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-99", NULL) == -EIO);
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-77", NULL) == -EIO);
|
||||
|
||||
assert_se(sd_bus_error_add_map(test_errors3) > 0);
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-88", NULL) == -888);
|
||||
assert_se(sd_bus_error_add_map(test_errors4) > 0);
|
||||
assert_se(sd_bus_error_add_map(test_errors4) == 0);
|
||||
assert_se(sd_bus_error_add_map(test_errors3) == 0);
|
||||
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-99", NULL) == -999);
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-77", NULL) == -777);
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-78", NULL) == -778);
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-2", NULL) == -52);
|
||||
assert_se(sd_bus_error_set(NULL, "org.freedesktop.custom-dbus-error-y", NULL) == -EIO);
|
||||
|
||||
assert_se(sd_bus_error_set(NULL, BUS_ERROR_NO_SUCH_UNIT, NULL) == -ENOENT);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
@ -22,52 +22,55 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-errors.h"
|
||||
|
||||
SD_BUS_ERROR_MAPPING(systemd_shared) = {
|
||||
{BUS_ERROR_NO_SUCH_UNIT, ENOENT},
|
||||
{BUS_ERROR_NO_UNIT_FOR_PID, ESRCH},
|
||||
{BUS_ERROR_UNIT_EXISTS, EEXIST},
|
||||
{BUS_ERROR_LOAD_FAILED, EIO},
|
||||
{BUS_ERROR_JOB_FAILED, EREMOTEIO},
|
||||
{BUS_ERROR_NO_SUCH_JOB, ENOENT},
|
||||
{BUS_ERROR_NOT_SUBSCRIBED, EINVAL},
|
||||
{BUS_ERROR_ALREADY_SUBSCRIBED, EINVAL},
|
||||
{BUS_ERROR_ONLY_BY_DEPENDENCY, EINVAL},
|
||||
{BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, EDEADLOCK},
|
||||
{BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, EDEADLOCK},
|
||||
{BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, EDEADLOCK},
|
||||
{BUS_ERROR_UNIT_MASKED, ENOSYS},
|
||||
{BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, EBADR},
|
||||
{BUS_ERROR_NO_ISOLATION, EPERM},
|
||||
{BUS_ERROR_SHUTTING_DOWN, ECANCELED},
|
||||
{BUS_ERROR_SCOPE_NOT_RUNNING, EHOSTDOWN},
|
||||
BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map shared_errors[] = {
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_UNIT, ENOENT),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_UNIT_FOR_PID, ESRCH),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_EXISTS, EEXIST),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_LOAD_FAILED, EIO),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_JOB_FAILED, EREMOTEIO),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_JOB, ENOENT),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NOT_SUBSCRIBED, EINVAL),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_ALREADY_SUBSCRIBED, EINVAL),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_ONLY_BY_DEPENDENCY, EINVAL),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, EDEADLOCK),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, EDEADLOCK),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, EDEADLOCK),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_MASKED, ENOSYS),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, EBADR),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_ISOLATION, EPERM),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_SHUTTING_DOWN, ECANCELED),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_SCOPE_NOT_RUNNING, EHOSTDOWN),
|
||||
|
||||
{BUS_ERROR_NO_SUCH_MACHINE, ENXIO},
|
||||
{BUS_ERROR_NO_MACHINE_FOR_PID, ENXIO},
|
||||
{BUS_ERROR_MACHINE_EXISTS, EEXIST},
|
||||
{BUS_ERROR_NO_PRIVATE_NETWORKING, ENOSYS},
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_MACHINE, ENXIO),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_MACHINE_FOR_PID, ENXIO),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_MACHINE_EXISTS, EEXIST),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_PRIVATE_NETWORKING, ENOSYS),
|
||||
|
||||
{BUS_ERROR_NO_SUCH_SESSION, ENXIO},
|
||||
{BUS_ERROR_NO_SESSION_FOR_PID, ENXIO},
|
||||
{BUS_ERROR_NO_SUCH_USER, ENXIO},
|
||||
{BUS_ERROR_NO_USER_FOR_PID, ENXIO},
|
||||
{BUS_ERROR_NO_SUCH_SEAT, ENXIO},
|
||||
{BUS_ERROR_SESSION_NOT_ON_SEAT, EINVAL},
|
||||
{BUS_ERROR_NOT_IN_CONTROL, EINVAL},
|
||||
{BUS_ERROR_DEVICE_IS_TAKEN, EINVAL},
|
||||
{BUS_ERROR_DEVICE_NOT_TAKEN, EINVAL},
|
||||
{BUS_ERROR_OPERATION_IN_PROGRESS, EINPROGRESS},
|
||||
{BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, ENOSYS},
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_SESSION, ENXIO),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SESSION_FOR_PID, ENXIO),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_USER, ENXIO),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_USER_FOR_PID, ENXIO),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_SEAT, ENXIO),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_SESSION_NOT_ON_SEAT, EINVAL),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NOT_IN_CONTROL, EINVAL),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_DEVICE_IS_TAKEN, EINVAL),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_DEVICE_NOT_TAKEN, EINVAL),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_OPERATION_IN_PROGRESS, EINPROGRESS),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, ENOSYS),
|
||||
|
||||
{BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED, EALREADY},
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED, EALREADY),
|
||||
|
||||
{BUS_ERROR_NO_SUCH_PROCESS, ESRCH},
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_PROCESS, ESRCH),
|
||||
|
||||
{BUS_ERROR_NO_NAME_SERVERS, EIO},
|
||||
{BUS_ERROR_INVALID_REPLY, EINVAL},
|
||||
{BUS_ERROR_NO_SUCH_RR, ENOENT},
|
||||
{BUS_ERROR_NO_RESOURCES, ENOMEM},
|
||||
{BUS_ERROR_CNAME_LOOP, EDEADLOCK},
|
||||
{BUS_ERROR_ABORTED, ECANCELED},
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_NAME_SERVERS, EIO),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_INVALID_REPLY, EINVAL),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_RR, ENOENT),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_RESOURCES, ENOMEM),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_CNAME_LOOP, EDEADLOCK),
|
||||
SD_BUS_ERROR_MAP(BUS_ERROR_ABORTED, ECANCELED),
|
||||
|
||||
SD_BUS_ERROR_MAP_END
|
||||
};
|
||||
|
@ -22,6 +22,7 @@
|
||||
***/
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "bus-error.h"
|
||||
|
||||
#define BUS_ERROR_NO_SUCH_UNIT "org.freedesktop.systemd1.NoSuchUnit"
|
||||
#define BUS_ERROR_NO_UNIT_FOR_PID "org.freedesktop.systemd1.NoUnitForPID"
|
||||
@ -70,4 +71,4 @@
|
||||
#define BUS_ERROR_ABORTED "org.freedesktop.resolve1.Aborted"
|
||||
#define _BUS_ERROR_DNS "org.freedesktop.resolve1.DnsError."
|
||||
|
||||
SD_BUS_ERROR_MAPPING_USE(systemd_shared);
|
||||
BUS_ERROR_MAP_ELF_USE(shared_errors);
|
||||
|
@ -95,15 +95,15 @@
|
||||
#error "Wut? Pointers are neither 4 nor 8 bytes long?"
|
||||
#endif
|
||||
|
||||
#define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) p))
|
||||
#define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) p))
|
||||
#define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) p))
|
||||
#define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) (p)))
|
||||
#define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) (p)))
|
||||
#define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) (p)))
|
||||
|
||||
static inline size_t ALIGN_TO(size_t l, size_t ali) {
|
||||
return ((l + ali - 1) & ~(ali - 1));
|
||||
}
|
||||
|
||||
#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p, ali))
|
||||
#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) (p), (ali)))
|
||||
|
||||
/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */
|
||||
static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
||||
|
@ -46,6 +46,11 @@ typedef struct {
|
||||
int _need_free;
|
||||
} sd_bus_error;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
int code;
|
||||
} sd_bus_error_map;
|
||||
|
||||
/* Flags */
|
||||
|
||||
enum {
|
||||
@ -356,32 +361,9 @@ int sd_bus_creds_get_description(sd_bus_creds *c, const char **name);
|
||||
|
||||
/* Error structures */
|
||||
|
||||
struct sd_bus_name_error_mapping {
|
||||
const char* name;
|
||||
int code;
|
||||
};
|
||||
typedef struct sd_bus_name_error_mapping sd_bus_name_error_mapping;
|
||||
|
||||
#define SD_BUS_ERROR_MAKE_CONST(name, message) ((const sd_bus_error) {(name), (message), 0})
|
||||
#define SD_BUS_ERROR_NULL SD_BUS_ERROR_MAKE_CONST(NULL, NULL)
|
||||
|
||||
#ifndef SD_BUS_ERROR_MAPPING
|
||||
# define _SD_BUS_ERROR_XCONCAT(x, y) x ## y
|
||||
# define _SD_BUS_ERROR_CONCAT(x, y) _SD_BUS_ERROR_XCONCAT(x, y)
|
||||
# define SD_BUS_ERROR_MAPPING(name) \
|
||||
__attribute((__section__("sd_bus_errnomap"))) \
|
||||
__attribute((__used__)) \
|
||||
const sd_bus_name_error_mapping _SD_BUS_ERROR_CONCAT(_sd_bus_errno_mapping_, name)[]
|
||||
# define SD_BUS_ERROR_MAPPING_USE(name) \
|
||||
extern \
|
||||
const sd_bus_name_error_mapping _SD_BUS_ERROR_CONCAT(_sd_bus_errno_mapping_, name)[]; \
|
||||
__attribute((__used__)) \
|
||||
static const sd_bus_name_error_mapping* \
|
||||
_SD_BUS_ERROR_CONCAT(sd_bus_name_error_mapping_ref, __COUNTER__) \
|
||||
= _SD_BUS_ERROR_CONCAT(_sd_bus_errno_mapping_, name);
|
||||
#endif
|
||||
|
||||
|
||||
void sd_bus_error_free(sd_bus_error *e);
|
||||
int sd_bus_error_set(sd_bus_error *e, const char *name, const char *message);
|
||||
int sd_bus_error_setf(sd_bus_error *e, const char *name, const char *format, ...) _sd_printf_(3, 4);
|
||||
@ -393,6 +375,19 @@ int sd_bus_error_copy(sd_bus_error *dest, const sd_bus_error *e);
|
||||
int sd_bus_error_is_set(const sd_bus_error *e);
|
||||
int sd_bus_error_has_name(const sd_bus_error *e, const char *name);
|
||||
|
||||
#define SD_BUS_ERROR_MAP(_name, _code) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.code = _code, \
|
||||
}
|
||||
#define SD_BUS_ERROR_MAP_END \
|
||||
{ \
|
||||
.name = NULL, \
|
||||
.code = - 'x', \
|
||||
}
|
||||
|
||||
int sd_bus_error_add_map(const sd_bus_error_map *map);
|
||||
|
||||
/* Auxiliary macros */
|
||||
|
||||
#define SD_BUS_MESSAGE_APPEND_ID128(x) 16, \
|
||||
|
@ -38,14 +38,16 @@
|
||||
#include "fileio-label.h"
|
||||
#include "label.h"
|
||||
#include "bus-util.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-errors.h"
|
||||
#include "event-util.h"
|
||||
|
||||
#define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n"
|
||||
#define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n"
|
||||
|
||||
SD_BUS_ERROR_MAPPING(timedated) = {
|
||||
{"org.freedesktop.timedate1.NoNTPSupport", ENOTSUP},
|
||||
static BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map timedated_errors[] = {
|
||||
SD_BUS_ERROR_MAP("org.freedesktop.timedate1.NoNTPSupport", ENOTSUP),
|
||||
SD_BUS_ERROR_MAP_END
|
||||
};
|
||||
|
||||
typedef struct Context {
|
||||
|
Loading…
Reference in New Issue
Block a user