diff mbox series

[2/4] useful: Add a cleanup handler for fd variables

Message ID 20220701133237.2887854-2-andrew.zaborowski@intel.com (mailing list archive)
State Accepted, archived
Headers show
Series [1/4] dhcp: Set lease->bound_time before emitting event | expand

Commit Message

Andrew Zaborowski July 1, 2022, 1:32 p.m. UTC
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 mbox series

Patch

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