chiark / gitweb /
rtnl: introduce default timeout
[elogind.git] / src / libsystemd-rtnl / sd-rtnl.c
index abf45d0eed109b971e0c9c94700c6e693f666a56..b11a813dfe3cea502657b3b194dded9999eb563e 100644 (file)
@@ -47,8 +47,8 @@ static int sd_rtnl_new(sd_rtnl **ret) {
         return 0;
 }
 
-int sd_rtnl_open(__u32 groups, sd_rtnl **ret) {
-        sd_rtnl *rtnl;
+int sd_rtnl_open(uint32_t groups, sd_rtnl **ret) {
+        _cleanup_sd_rtnl_unref_ sd_rtnl *rtnl = NULL;
         int r;
 
         r = sd_rtnl_new(&rtnl);
@@ -56,22 +56,17 @@ int sd_rtnl_open(__u32 groups, sd_rtnl **ret) {
                 return r;
 
         rtnl->fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_ROUTE);
-        if (rtnl->fd < 0) {
-                r = -errno;
-                sd_rtnl_unref(rtnl);
-                return r;
-        }
+        if (rtnl->fd < 0)
+                return -errno;
 
         rtnl->sockaddr.nl.nl_groups = groups;
 
         r = bind(rtnl->fd, &rtnl->sockaddr.sa, sizeof(rtnl->sockaddr));
-        if (r < 0) {
-                r = -errno;
-                sd_rtnl_unref(rtnl);
-                return r;
-        }
+        if (r < 0)
+                return -errno;
 
         *ret = rtnl;
+        rtnl = NULL;
 
         return 0;
 }
@@ -94,11 +89,10 @@ sd_rtnl *sd_rtnl_unref(sd_rtnl *rtnl) {
 }
 
 int sd_rtnl_send_with_reply_and_block(sd_rtnl *nl,
-                                        sd_rtnl_message *message,
-                                        uint64_t usec,
-                                        sd_rtnl_message **ret) {
+                sd_rtnl_message *message,
+                uint64_t usec,
+                sd_rtnl_message **ret) {
         struct pollfd p[1] = {};
-        sd_rtnl_message *reply;
         struct timespec left;
         usec_t timeout;
         int r, serial;
@@ -115,10 +109,15 @@ int sd_rtnl_send_with_reply_and_block(sd_rtnl *nl,
         p[0].fd = nl->fd;
         p[0].events = POLLOUT;
 
-        timeout = now(CLOCK_MONOTONIC) + usec;
+        if (usec == (uint64_t) -1)
+                timeout = 0;
+        else if (usec == 0)
+                timeout = now(CLOCK_MONOTONIC) + RTNL_DEFAULT_TIMEOUT;
+        else
+                timeout = now(CLOCK_MONOTONIC) + usec;
 
         for (;;) {
-                if (usec != (uint64_t) -1) {
+                if (timeout) {
                         usec_t n;
 
                         n = now(CLOCK_MONOTONIC);
@@ -128,7 +127,7 @@ int sd_rtnl_send_with_reply_and_block(sd_rtnl *nl,
                         timespec_store(&left, timeout - n);
                 }
 
-                r = ppoll(p, 1, usec == (uint64_t) -1 ? NULL : &left, NULL);
+                r = ppoll(p, 1, timeout ? &left : NULL, NULL);
                 if (r < 0)
                         return 0;
 
@@ -144,7 +143,9 @@ int sd_rtnl_send_with_reply_and_block(sd_rtnl *nl,
         p[0].events = POLLIN;
 
         for (;;) {
-                if (usec != (uint64_t) -1) {
+                _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *reply = NULL;
+
+                if (timeout) {
                         usec_t n;
 
                         n = now(CLOCK_MONOTONIC);
@@ -154,7 +155,7 @@ int sd_rtnl_send_with_reply_and_block(sd_rtnl *nl,
                         timespec_store(&left, timeout - n);
                 }
 
-                r = ppoll(p, 1, usec == (uint64_t) -1 ? NULL : &left, NULL);
+                r = ppoll(p, 1, timeout ? &left : NULL, NULL);
                 if (r < 0)
                         return r;
 
@@ -167,20 +168,16 @@ int sd_rtnl_send_with_reply_and_block(sd_rtnl *nl,
 
                         if (received_serial == serial) {
                                 r = message_get_errno(reply);
-                                if (r < 0) {
-                                        sd_rtnl_message_unref(reply);
+                                if (r < 0)
                                         return r;
-                                }
 
-                                if (ret)
+                                if (ret) {
                                         *ret = reply;
-                                else
-                                        reply = sd_rtnl_message_unref(reply);
+                                        reply = NULL;
+                                }
 
                                 break;;
                         }
-
-                        reply = sd_rtnl_message_unref(reply);
                 }
         }