Add an assert() variant that we may call between fork() and exec*().
Signed-off-by: Laszlo Ersek <lersek(a)redhat.com>
---
Notes:
v4:
- rework with xwritel()
- do not pick up R-b tags due to the above
context:-U13
lib/internal.h | 13 +++++++++++++
lib/utils.c | 16 ++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/lib/internal.h b/lib/internal.h
index 73d243a13743..4e75f97d2a8a 100644
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -517,14 +517,27 @@ extern char *nbd_internal_printable_string (const char *str)
extern char *nbd_internal_printable_string_list (char **list)
LIBNBD_ATTRIBUTE_ALLOC_DEALLOC (free);
/* These are wrappers around socket(2) and socketpair(2). They
* always set SOCK_CLOEXEC. nbd_internal_socket can set SOCK_NONBLOCK
* according to the nonblock parameter.
*/
extern int nbd_internal_socket (int domain, int type, int protocol,
bool nonblock);
extern int nbd_internal_socketpair (int domain, int type, int protocol,
int *fds)
LIBNBD_ATTRIBUTE_NONNULL (4);
+extern void nbd_internal_fork_safe_assert (int result, const char *file,
+ long line, const char *func,
+ const char *assertion)
+ LIBNBD_ATTRIBUTE_NONNULL (2, 4, 5);
+
+#ifdef NDEBUG
+#define NBD_INTERNAL_FORK_SAFE_ASSERT(expression) ((void)0)
+#else
+#define NBD_INTERNAL_FORK_SAFE_ASSERT(expression) \
+ (nbd_internal_fork_safe_assert ((expression) != 0, __FILE__, __LINE__, \
+ __func__, #expression))
+#endif
+
#endif /* LIBNBD_INTERNAL_H */
diff --git a/lib/utils.c b/lib/utils.c
index 62b4bfdda5c3..255f428dd8b6 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -479,13 +479,29 @@ nbd_internal_socketpair (int domain, int type, int protocol, int
*fds)
if (ret == 0) {
for (i = 0; i < 2; i++) {
if (fcntl (fds[i], F_SETFD, FD_CLOEXEC) == -1) {
close (fds[0]);
close (fds[1]);
return -1;
}
}
}
#endif
return ret;
}
+
+void
+nbd_internal_fork_safe_assert (int result, const char *file, long line,
+ const char *func, const char *assertion)
+{
+ const char *line_out;
+ char line_buf[32];
+
+ if (result)
+ return;
+
+ line_out = nbd_internal_fork_safe_itoa (line, line_buf, sizeof line_buf);
+ xwritel (STDERR_FILENO, file, ":", line_out, ": ", func, ":
Assertion `",
+ assertion, "' failed.\n", (char *)NULL);
+ abort ();
+}