From: Zbigniew Jędrzejewski-Szmek Date: Fri, 31 Oct 2014 00:31:48 +0000 (-0400) Subject: bus: add sd_bus_errnomap section X-Git-Tag: v218~645 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=4a0a74179fcfb85c456794fd91fa2ae5d4d3bc8f;hp=e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5 bus: add sd_bus_errnomap section This allows custom "name" ↔ errno mappings to be registered. Tables from all compilation units are concatenated. --- diff --git a/Makefile.am b/Makefile.am index 3b273d492..f1a972dc6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/src/libsystemd/sd-bus/.gitignore b/src/libsystemd/sd-bus/.gitignore deleted file mode 100644 index d32542e2a..000000000 --- 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 59eaa3554..000000000 --- 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 af83c12d5..2e64b925f 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 cf0ad9d54..146948618 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 b78be5499..dd0cca4ab 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 18acfc2ad..c95b5e7ab 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);