chiark / gitweb /
bus: reenable id change subscriptions
[elogind.git] / src / libsystemd-bus / bus-error.c
index 968e80df7dc80221cce62f9544e40b0b7fd13804..35bd4f0dafac4217469d61709837b9861568d84b 100644 (file)
 static int bus_error_name_to_errno(const char *name) {
         const char *p;
         int r;
+        const name_error_mapping *m;
 
         if (!name)
                 return EINVAL;
 
-        p = startswith(name, "Posix.Error.");
+        p = startswith(name, "System.Error.");
         if (p) {
                 r = errno_from_name(p);
                 if (r <= 0)
@@ -51,81 +52,9 @@ static int bus_error_name_to_errno(const char *name) {
                 return r;
         }
 
-        /* Better replace this with a gperf table */
-
-        if (streq(name, SD_BUS_ERROR_NO_MEMORY))
-                return ENOMEM;
-
-        if (streq(name, SD_BUS_ERROR_SERVICE_UNKNOWN))
-                return EHOSTUNREACH;
-
-        if (streq(name, SD_BUS_ERROR_NAME_HAS_NO_OWNER))
-                return ENXIO;
-
-        if (streq(name, SD_BUS_ERROR_NO_REPLY) ||
-            streq(name, SD_BUS_ERROR_TIMEOUT) ||
-            streq(name, "org.freedesktop.DBus.Error.TimedOut"))
-                return ETIMEDOUT;
-
-        if (streq(name, SD_BUS_ERROR_IO_ERROR))
-                return EIO;
-
-        if (streq(name, SD_BUS_ERROR_BAD_ADDRESS))
-                return EADDRNOTAVAIL;
-
-        if (streq(name, SD_BUS_ERROR_NOT_SUPPORTED))
-                return ENOTSUP;
-
-        if (streq(name, SD_BUS_ERROR_LIMITS_EXCEEDED))
-                return ENOBUFS;
-
-        if (streq(name, SD_BUS_ERROR_ACCESS_DENIED) ||
-            streq(name, SD_BUS_ERROR_AUTH_FAILED))
-                return EACCES;
-
-        if (streq(name, SD_BUS_ERROR_NO_SERVER))
-                return EHOSTDOWN;
-
-        if (streq(name, SD_BUS_ERROR_NO_NETWORK))
-                return ENONET;
-
-        if (streq(name, SD_BUS_ERROR_ADDRESS_IN_USE))
-                return EADDRINUSE;
-
-        if (streq(name, SD_BUS_ERROR_DISCONNECTED))
-                return ECONNRESET;
-
-        if (streq(name, SD_BUS_ERROR_INVALID_ARGS) ||
-            streq(name, SD_BUS_ERROR_INVALID_SIGNATURE) ||
-            streq(name, "org.freedesktop.DBus.Error.MatchRuleInvalid") ||
-            streq(name, "org.freedesktop.DBus.Error.InvalidFileContent"))
-                return EINVAL;
-
-        if (streq(name, SD_BUS_ERROR_FILE_NOT_FOUND) ||
-            streq(name, "org.freedesktop.DBus.Error.MatchRuleNotFound"))
-                return ENOENT;
-
-        if (streq(name, SD_BUS_ERROR_FILE_EXISTS))
-                return EEXIST;
-
-        if (streq(name, SD_BUS_ERROR_UNKNOWN_METHOD) ||
-            streq(name, SD_BUS_ERROR_UNKNOWN_OBJECT) ||
-            streq(name, SD_BUS_ERROR_UNKNOWN_INTERFACE) ||
-            streq(name, SD_BUS_ERROR_UNKNOWN_PROPERTY))
-                return EBADR;
-
-        if (streq(name, SD_BUS_ERROR_PROPERTY_READ_ONLY))
-                return EROFS;
-
-        if (streq(name, SD_BUS_ERROR_UNIX_PROCESS_ID_UNKNOWN) ||
-            streq(name, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"))
-                return ESRCH;
-
-        if (streq(name, SD_BUS_ERROR_INCONSISTENT_MESSAGE))
-                return EBADMSG;
-
-        if (streq(name, "org.freedesktop.DBus.Error.ObjectPathInUse"))
-                return EBUSY;
+        m = bus_error_mapping_lookup(name, strlen(name));
+        if (m)
+                return m->code;
 
         return EIO;
 }
@@ -198,7 +127,7 @@ static int errno_to_bus_error_name_new(int error, char **ret) {
         if (!name)
                 return 0;
 
-        n = strappend("Posix.Error.", name);
+        n = strappend("System.Error.", name);
         if (!n)
                 return -ENOMEM;
 
@@ -210,20 +139,20 @@ bool bus_error_is_dirty(sd_bus_error *e) {
         if (!e)
                 return false;
 
-        return e->name || e->message || e->need_free;
+        return e->name || e->message || e->_need_free != 0;
 }
 
 _public_ void sd_bus_error_free(sd_bus_error *e) {
         if (!e)
                 return;
 
-        if (e->need_free) {
+        if (e->_need_free > 0) {
                 free((void*) e->name);
                 free((void*) e->message);
         }
 
         e->name = e->message = NULL;
-        e->need_free = false;
+        e->_need_free = 0;
 }
 
 _public_ int sd_bus_error_set(sd_bus_error *e, const char *name, const char *message) {
@@ -244,7 +173,7 @@ _public_ int sd_bus_error_set(sd_bus_error *e, const char *name, const char *mes
         if (message)
                 e->message = strdup(message);
 
-        e->need_free = true;
+        e->_need_free = 1;
 
 finish:
         return -bus_error_name_to_errno(name);
@@ -268,7 +197,7 @@ int bus_error_setfv(sd_bus_error *e, const char *name, const char *format, va_li
         if (format)
                 vasprintf((char**) &e->message, format, ap);
 
-        e->need_free = true;
+        e->_need_free = 1;
 
 finish:
         return -bus_error_name_to_errno(name);
@@ -299,7 +228,13 @@ _public_ int sd_bus_error_copy(sd_bus_error *dest, const sd_bus_error *e) {
 
         assert_return(!bus_error_is_dirty(dest), -EINVAL);
 
-        if (!e->need_free)
+        /*
+         * _need_free  < 0 indicates that the error is temporarily const, needs deep copying
+         * _need_free == 0 indicates that the error is perpetually const, needs no deep copying
+         * _need_free  > 0 indicates that the error is fully dynamic, needs deep copying
+         */
+
+        if (e->_need_free == 0)
                 *dest = *e;
         else {
                 dest->name = strdup(e->name);
@@ -311,7 +246,7 @@ _public_ int sd_bus_error_copy(sd_bus_error *dest, const sd_bus_error *e) {
                 if (e->message)
                         dest->message = strdup(e->message);
 
-                dest->need_free = true;
+                dest->_need_free = 1;
         }
 
 finish:
@@ -380,7 +315,7 @@ static void bus_error_strerror(sd_bus_error *e, int error) {
                 }
 
                 if (x == m) {
-                        if (e->need_free) {
+                        if (e->_need_free > 0) {
                                 /* Error is already dynamic, let's just update the message */
                                 free((char*) e->message);
                                 e->message = x;
@@ -395,14 +330,14 @@ static void bus_error_strerror(sd_bus_error *e, int error) {
                                         return;
                                 }
 
-                                e->need_free = true;
+                                e->_need_free = 1;
                                 e->name = t;
                                 e->message = x;
                         }
                 } else {
                         free(m);
 
-                        if (e->need_free) {
+                        if (e->_need_free > 0) {
                                 char *t;
 
                                 /* Error is dynamic, let's hence make the message also dynamic */
@@ -444,7 +379,7 @@ _public_ int sd_bus_error_set_errno(sd_bus_error *e, int error) {
 
                 k = errno_to_bus_error_name_new(error, (char**) &e->name);
                 if (k > 0)
-                        e->need_free = true;
+                        e->_need_free = 1;
                 else if (k < 0) {
                         *e = BUS_ERROR_OOM;
                         return -error;
@@ -480,7 +415,7 @@ int bus_error_set_errnofv(sd_bus_error *e, int error, const char *format, va_lis
 
                 k = errno_to_bus_error_name_new(error, (char**) &e->name);
                 if (k > 0)
-                        e->need_free = true;
+                        e->_need_free = 1;
                 else if (k < 0) {
                         *e = BUS_ERROR_OOM;
                         return -ENOMEM;
@@ -496,12 +431,12 @@ int bus_error_set_errnofv(sd_bus_error *e, int error, const char *format, va_lis
                 r = vasprintf(&m, format, ap);
                 if (r >= 0) {
 
-                        if (!e->need_free) {
+                        if (e->_need_free <= 0) {
                                 char *t;
 
                                 t = strdup(e->name);
                                 if (t) {
-                                        e->need_free = true;
+                                        e->_need_free = 1;
                                         e->name = t;
                                         e->message = m;
                                         return -error;