From 4a0a74179fcfb85c456794fd91fa2ae5d4d3bc8f Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Thu, 30 Oct 2014 20:31:48 -0400 Subject: bus: add sd_bus_errnomap section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows custom "name" ↔ errno mappings to be registered. Tables from all compilation units are concatenated. --- src/libsystemd/sd-bus/.gitignore | 1 - src/libsystemd/sd-bus/bus-error-mapping.gperf | 50 ----------------------- src/libsystemd/sd-bus/bus-error.c | 58 ++++++++++++++++++++++++--- src/libsystemd/sd-bus/bus-error.h | 2 - src/libsystemd/sd-bus/test-bus-error.c | 28 ++++++++++++- src/systemd/sd-bus.h | 13 ++++++ 6 files changed, 91 insertions(+), 61 deletions(-) delete mode 100644 src/libsystemd/sd-bus/.gitignore delete mode 100644 src/libsystemd/sd-bus/bus-error-mapping.gperf (limited to 'src') diff --git a/src/libsystemd/sd-bus/.gitignore b/src/libsystemd/sd-bus/.gitignore deleted file mode 100644 index d32542e2a6..0000000000 --- a/src/libsystemd/sd-bus/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/bus-error-mapping.c diff --git a/src/libsystemd/sd-bus/bus-error-mapping.gperf b/src/libsystemd/sd-bus/bus-error-mapping.gperf deleted file mode 100644 index 59eaa3554b..0000000000 --- a/src/libsystemd/sd-bus/bus-error-mapping.gperf +++ /dev/null @@ -1,50 +0,0 @@ -%{ -#include -#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 diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c index af83c12d53..2e64b925f3 100644 --- a/src/libsystemd/sd-bus/bus-error.c +++ b/src/libsystemd/sd-bus/bus-error.c @@ -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) { diff --git a/src/libsystemd/sd-bus/bus-error.h b/src/libsystemd/sd-bus/bus-error.h index cf0ad9d545..1469486187 100644 --- a/src/libsystemd/sd-bus/bus-error.h +++ b/src/libsystemd/sd-bus/bus-error.h @@ -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); diff --git a/src/libsystemd/sd-bus/test-bus-error.c b/src/libsystemd/sd-bus/test-bus-error.c index b78be5499c..dd0cca4ab8 100644 --- a/src/libsystemd/sd-bus/test-bus-error.c +++ b/src/libsystemd/sd-bus/test-bus-error.c @@ -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; } diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index 18acfc2ad7..c95b5e7ab0 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -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); -- cgit v1.2.3-54-g00ecf