chiark / gitweb /
units: fix logger/initctl paths
[elogind.git] / socket-util.c
index 96567c6d81ec247e78e7303d483f166046633e05..8141ab09ebcd3fa0c08d4a715c1e873f84c2b262 100644 (file)
@@ -370,6 +370,88 @@ int socket_address_listen(
 
 fail:
         r = -errno;
-        close_nointr(fd);
+        close_nointr_nofail(fd);
         return r;
 }
+
+bool socket_address_can_accept(const SocketAddress *a) {
+        assert(a);
+
+        return
+                a->type == SOCK_STREAM ||
+                a->type == SOCK_SEQPACKET;
+}
+
+bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
+        assert(a);
+        assert(b);
+
+        /* Invalid addresses are unequal to all */
+        if (socket_address_verify(a) < 0 ||
+            socket_address_verify(b) < 0)
+                return false;
+
+        if (a->type != b->type)
+                return false;
+
+        if (a->size != b->size)
+                return false;
+
+        if (socket_address_family(a) != socket_address_family(b))
+                return false;
+
+        switch (socket_address_family(a)) {
+
+        case AF_INET:
+                if (a->sockaddr.in4.sin_addr.s_addr != b->sockaddr.in4.sin_addr.s_addr)
+                        return false;
+
+                if (a->sockaddr.in4.sin_port != b->sockaddr.in4.sin_port)
+                        return false;
+
+                break;
+
+        case AF_INET6:
+                if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
+                        return false;
+
+                if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
+                        return false;
+
+                break;
+
+        case AF_UNIX:
+
+                if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
+                        return false;
+
+                if (a->sockaddr.un.sun_path[0]) {
+                        if (strncmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, sizeof(a->sockaddr.un.sun_path)) != 0)
+                                return false;
+                } else {
+                        if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, sizeof(a->sockaddr.un.sun_path)) != 0)
+                                return false;
+                }
+
+                break;
+
+        default:
+                /* Cannot compare, so we assume the addresses are different */
+                return false;
+        }
+
+        return true;
+}
+
+bool socket_address_is(const SocketAddress *a, const char *s) {
+        struct SocketAddress b;
+
+        assert(a);
+        assert(s);
+
+        if (socket_address_parse(&b, s) < 0)
+                return false;
+
+        return socket_address_equal(a, &b);
+
+}