From 1bc1809e11759d9c0ff505f078943e73ded9db9c Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Wed, 18 Oct 2017 11:14:36 +0200 Subject: [PATCH] shared: introduce nm_close() nm_close() is like close(), but throws an assertion if the input fd is >=0 and invalid. Passing an invalid (i.e. already closed) fd to close() is a programming error with potentially catastrophic effects, as another thread may reuse the closed fd. --- shared/nm-utils/nm-macros-internal.h | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index bbdf50be71..a8f78e6d2d 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -59,6 +59,8 @@ #define nm_auto(fcn) __attribute__ ((cleanup(fcn))) +static inline int nm_close (int fd); + /** * nm_auto_free: * @@ -96,7 +98,7 @@ _nm_auto_close_impl (int *pfd) if (*pfd >= 0) { int errsv = errno; - (void) close (*pfd); + (void) nm_close (*pfd); errno = errsv; } } @@ -1149,4 +1151,22 @@ nm_decode_version (guint version, guint *major, guint *minor, guint *micro) /*****************************************************************************/ +/** + * nm_close: + * + * Like close() but throws an assertion if the input fd is + * invalid. Closing an invalid fd is a programming error, so + * it's better to catch it early. + */ +static inline int +nm_close (int fd) +{ + if (fd >= 0) { + if (close (fd) == 0) + return 0; + nm_assert (errno != EBADF); + } + return -1; +} + #endif /* __NM_MACROS_INTERNAL_H__ */