]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
lib/: exit_if_null(): Add macro to exit(3) on error
authorAlejandro Colomar <alx@kernel.org>
Tue, 5 Dec 2023 12:46:23 +0000 (13:46 +0100)
committerIker Pedrosa <ikerpedrosam@gmail.com>
Mon, 27 Oct 2025 13:32:06 +0000 (14:32 +0100)
Writing an x*() variant function of several functions is unnecessary.
It's simpler to write a generic exit_if_null() macro that can be chained
with any other calls.  With such a macro, the x*() variants can be
implemented as one-liner macros that are much easier to read:

For example:

#define xmalloc(size)  exit_if_null(malloc(size))

If an error is detected, log an error, and exit(13).  About why 13, I
don't really know.  It's just what was used previously in xmalloc().

Signed-off-by: Alejandro Colomar <alx@kernel.org>
lib/Makefile.am
lib/exit_if_null.c [new file with mode: 0644]
lib/exit_if_null.h [new file with mode: 0644]

index dc701148e11b0358853033a3a05f08693ca321c7..45d9b1ec2d9d002438f0919f07006bc54d760b4c 100644 (file)
@@ -90,6 +90,8 @@ libshadow_la_SOURCES = \
        defines.h \
        encrypt.c \
        env.c \
+       exit_if_null.c \
+       exit_if_null.h \
        exitcodes.h \
        faillog.h \
        failure.c \
diff --git a/lib/exit_if_null.c b/lib/exit_if_null.c
new file mode 100644 (file)
index 0000000..9d68eaf
--- /dev/null
@@ -0,0 +1,10 @@
+// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
+// SPDX-License-Identifier: BSD-3-Clause
+
+
+#include "config.h"
+
+#include "exit_if_null.h"
+
+
+extern inline void exit_if_null_(void *p);
diff --git a/lib/exit_if_null.h b/lib/exit_if_null.h
new file mode 100644 (file)
index 0000000..93b6e47
--- /dev/null
@@ -0,0 +1,50 @@
+// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
+// SPDX-License-Identifier: BSD-3-Clause
+
+
+#ifndef SHADOW_INCLUDE_LIB_EXIT_IF_NULL_H_
+#define SHADOW_INCLUDE_LIB_EXIT_IF_NULL_H_
+
+
+#include "config.h"
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "shadowlog.h"
+
+
+/*
+ * This macro is used for implementing x*() variants of functions that
+ * allocate memory, such as xstrdup() for wrapping strdup(3).  The macro
+ * returns the input pointer transparently, with the same type, but
+ * calls exit(3) if the input is a null pointer (thus, if the allocation
+ * failed).
+ */
+#define exit_if_null(p)                                               \
+({                                                                    \
+       __auto_type  p_ = p;                                          \
+                                                                      \
+       exit_if_null_(p_);                                            \
+       p_;                                                           \
+})
+
+
+inline void exit_if_null_(void *p);
+
+
+inline void
+exit_if_null_(void *p)
+{
+       if (p == NULL) {
+               fprintf(log_get_logfd(), "%s: %s\n",
+                       log_get_progname(), strerror(errno));
+               exit(13);
+       }
+}
+
+
+#endif  // include guard