bus: add sd_bus_errnomap section
This allows custom "name" ↔ errno mappings to be registered. Tables from all compilation units are concatenated.
This commit is contained in:
+2
-5
@@ -2592,8 +2592,7 @@ libsystemd_internal_la_SOURCES = \
|
||||
src/libsystemd/sd-network/network-util.c
|
||||
|
||||
nodist_libsystemd_internal_la_SOURCES = \
|
||||
src/libsystemd/libsystemd.sym \
|
||||
src/libsystemd/sd-bus/bus-error-mapping.c
|
||||
src/libsystemd/libsystemd.sym
|
||||
|
||||
libsystemd_internal_la_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
@@ -2631,13 +2630,11 @@ noinst_LTLIBRARIES += \
|
||||
EXTRA_DIST += \
|
||||
src/libsystemd/libsystemd.sym.m4 \
|
||||
src/libsystemd/libsystemd.pc.in \
|
||||
src/libsystemd/sd-bus/bus-error-mapping.gperf \
|
||||
src/libsystemd/sd-bus/DIFFERENCES \
|
||||
src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
|
||||
|
||||
CLEANFILES += \
|
||||
src/libsystemd/libsystemd.sym \
|
||||
src/libsystemd/sd-bus/bus-error-mapping.c
|
||||
src/libsystemd/libsystemd.sym
|
||||
|
||||
BUILT_SOURCES += \
|
||||
src/libsystemd/libsystemd.sym
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
/bus-error-mapping.c
|
||||
@@ -1,50 +0,0 @@
|
||||
%{
|
||||
#include <errno.h>
|
||||
#include "bus-error.h"
|
||||
%}
|
||||
name_error_mapping;
|
||||
%null_strings
|
||||
%language=ANSI-C
|
||||
%define slot-name name
|
||||
%define hash-function-name bus_error_mapping_hash
|
||||
%define lookup-function-name bus_error_mapping_lookup
|
||||
%readonly-tables
|
||||
%omit-struct-type
|
||||
%struct-type
|
||||
%includes
|
||||
%%
|
||||
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
|
||||
@@ -35,10 +35,60 @@
|
||||
#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 = {
|
||||
{"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},
|
||||
};
|
||||
|
||||
extern const sd_bus_name_error_mapping __start_sd_bus_errnomap[];
|
||||
extern const sd_bus_name_error_mapping __stop_sd_bus_errnomap[];
|
||||
|
||||
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 (strneq(m->name, name, len))
|
||||
return m->code;
|
||||
|
||||
return EIO;
|
||||
}
|
||||
|
||||
static int bus_error_name_to_errno(const char *name) {
|
||||
const char *p;
|
||||
int r;
|
||||
const name_error_mapping *m;
|
||||
|
||||
if (!name)
|
||||
return EINVAL;
|
||||
@@ -52,11 +102,7 @@ static int bus_error_name_to_errno(const char *name) {
|
||||
return r;
|
||||
}
|
||||
|
||||
m = bus_error_mapping_lookup(name, strlen(name));
|
||||
if (m)
|
||||
return m->code;
|
||||
|
||||
return EIO;
|
||||
return bus_error_mapping_lookup(name, strlen(name));
|
||||
}
|
||||
|
||||
static sd_bus_error errno_to_bus_error_const(int error) {
|
||||
|
||||
@@ -32,8 +32,6 @@ struct name_error_mapping {
|
||||
};
|
||||
typedef struct name_error_mapping name_error_mapping;
|
||||
|
||||
const name_error_mapping* bus_error_mapping_lookup(const char *str, unsigned int len);
|
||||
|
||||
bool bus_error_is_dirty(sd_bus_error *e);
|
||||
|
||||
const char *bus_error_message(const sd_bus_error *e, int error);
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
#include "bus-error.h"
|
||||
#include "bus-util.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
static void test_error(void) {
|
||||
_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 = {
|
||||
@@ -110,6 +109,31 @@ int main(int argc, char *argv[]) {
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
SD_BUS_ERROR_MAPPING = {
|
||||
{"org.freedesktop.custom-dbus-error", 5},
|
||||
{"org.freedesktop.custom-dbus-error-2", 52},
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
test_error();
|
||||
test_errno_mapping_standard();
|
||||
test_errno_mapping_custom();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -326,8 +326,21 @@ int sd_bus_creds_get_connection_name(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 \
|
||||
__attribute((__section__("sd_bus_errnomap"))) __attribute((__used__)) \
|
||||
static const sd_bus_name_error_mapping _SD_BUS_ERROR_CONCAT(_sd_bus_errno_mapping_, __COUNTER__)[]
|
||||
#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);
|
||||
|
||||
Reference in New Issue
Block a user