[PATCH 2/4] useful: Add a cleanup handler for fd variables
Andrew Zaborowski <[email protected]>
| Newsgroups | dev.linux.lists.ell |
|---|---|
| Message-ID | <[email protected]> |
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.
---
ell/netconfig.c | 5 ++---
ell/useful.h | 14 ++++++++++++++
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/ell/netconfig.c b/ell/netconfig.c
index d4487bd..19aaf56 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 4c8b23e..791fa20 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
--
2.34.1