diff options
author | Andrew Zaborowski <andrew.zaborowski@intel.com> | 2022-07-01 15:32:35 +0200 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2022-07-01 10:11:06 -0500 |
commit | 91c066f3600afbe40a62d346b413fee22e49c89a (patch) | |
tree | b3ccbedf4e8d86a901bac1da68c21408d9a7398d | |
parent | ae663f5cb0341db25b1dc97d3882ce7dad46afae (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.c | 5 | ||||
-rw-r--r-- | ell/useful.h | 14 |
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 |