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:
Zbigniew Jędrzejewski-Szmek
2014-10-30 20:31:48 -04:00
parent e1323fbfbe
commit 4a0a74179f
7 changed files with 93 additions and 66 deletions
+2 -5
View File
@@ -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
View File
@@ -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
+52 -6
View File
@@ -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) {
-2
View File
@@ -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);
+26 -2
View File
@@ -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;
}
+13
View File
@@ -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);