chiark / gitweb /
sd-rtnl: types - don't assert_return in private API
[elogind.git] / src / libsystemd / sd-rtnl / sd-rtnl.c
index 7f1ec308a8e79a4d739d76684db3b5c8751f193c..ae49c77e018f4e023c11b519453e4de01c4d6b38 100644 (file)
@@ -67,6 +67,31 @@ static int sd_rtnl_new(sd_rtnl **ret) {
         return 0;
 }
 
+int sd_rtnl_new_from_netlink(sd_rtnl **ret, int fd) {
+        _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
+        socklen_t addrlen;
+        int r;
+
+        assert_return(ret, -EINVAL);
+
+        r = sd_rtnl_new(&rtnl);
+        if (r < 0)
+                return r;
+
+        addrlen = sizeof(rtnl->sockaddr);
+
+        r = getsockname(fd, &rtnl->sockaddr.sa, &addrlen);
+        if (r < 0)
+                return -errno;
+
+        rtnl->fd = fd;
+
+        *ret = rtnl;
+        rtnl = NULL;
+
+        return 0;
+}
+
 static bool rtnl_pid_changed(sd_rtnl *rtnl) {
         assert(rtnl);
 
@@ -121,12 +146,13 @@ static int rtnl_open_fd_ap(sd_rtnl **ret, int fd, unsigned n_groups, va_list ap)
         addrlen = sizeof(rtnl->sockaddr);
 
         r = bind(fd, &rtnl->sockaddr.sa, addrlen);
-        if (r < 0)
+        /* ignore EINVAL to allow opening an already bound socket */
+        if (r < 0 && errno != EINVAL)
                 return -errno;
 
         r = getsockname(fd, &rtnl->sockaddr.sa, &addrlen);
         if (r < 0)
-                return r;
+                return -errno;
 
         rtnl->fd = fd;