aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Zaborowski <andrew.zaborowski@intel.com>2022-07-01 15:32:35 +0200
committerDenis Kenzior <denkenz@gmail.com>2022-07-01 10:11:06 -0500
commit91c066f3600afbe40a62d346b413fee22e49c89a (patch)
treeb3ccbedf4e8d86a901bac1da68c21408d9a7398d
parentae663f5cb0341db25b1dc97d3882ce7dad46afae (diff)
useful: Add a cleanup handler for fd variables
Allow declaring an fd variable with a simple _auto_(close) int fd = -1; to be able to skip the close() call. This is useful for very simple file accesses where it's not worth using l_io with l_io_set_close_on_destroy. As an example, update netconfig_proc_write_ipv6_setting to use _auto_(close) where it helps in returning the errno from the read() call (on error) which would otherwise be clobbered by the close() call.
-rw-r--r--ell/netconfig.c5
-rw-r--r--ell/useful.h14
2 files changed, 16 insertions, 3 deletions
diff --git a/ell/netconfig.c b/ell/netconfig.c
index d4487bd2..19aaf566 100644
--- a/ell/netconfig.c
+++ b/ell/netconfig.c
@@ -968,7 +968,7 @@ static int netconfig_proc_write_ipv6_setting(struct l_netconfig *nc,
{
char ifname[IF_NAMESIZE];
_auto_(l_free) char *filename = NULL;
- int fd;
+ _auto_(close) int fd = -1;
int r;
if (unlikely(!if_indextoname(nc->ifindex, ifname)))
@@ -982,8 +982,7 @@ static int netconfig_proc_write_ipv6_setting(struct l_netconfig *nc,
return -errno;
r = L_TFR(write(fd, value, strlen(value)));
- L_TFR(close(fd));
- return r;
+ return r > 0 ? 0 : -errno;
}
LIB_EXPORT struct l_netconfig *l_netconfig_new(uint32_t ifindex)
diff --git a/ell/useful.h b/ell/useful.h
index 4c8b23ea..791fa200 100644
--- a/ell/useful.h
+++ b/ell/useful.h
@@ -20,6 +20,11 @@
*
*/
+#include <unistd.h>
+#include <errno.h>
+
+#include <ell/util.h>
+
#define align_len(len, boundary) (((len)+(boundary)-1) & ~((boundary)-1))
#define likely(x) __builtin_expect(!!(x), 1)
@@ -65,6 +70,15 @@ static inline unsigned char bit_field(const unsigned char oct,
#define _auto_(func) \
__AUTODESTRUCT(func)
+/* Enables declaring _auto_(close) int fd = <-1 or L_TFR(open(...))>; */
+inline __attribute__((always_inline)) void close_cleanup(void *p)
+{
+ int fd = *(int *) p;
+
+ if (fd >= 0)
+ L_TFR(close(fd));
+}
+
/*
* Trick the compiler into thinking that var might be changed somehow by
* the asm