From fad5b725a63ea8bf369781ea24ba739584f2dfe0 Mon Sep 17 00:00:00 2001 From: Jakob Kaivo Date: Mon, 8 Jan 2024 16:03:32 -0500 Subject: add macro to assert signal-safety of library functions --- src/_assert.h | 60 +------------------------------------------ src/_safety.h | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/signal/__signal.c | 3 +++ src/signal/_signal.h | 8 ++++++ 4 files changed, 83 insertions(+), 59 deletions(-) create mode 100644 src/_safety.h create mode 100644 src/signal/__signal.c create mode 100644 src/signal/_signal.h diff --git a/src/_assert.h b/src/_assert.h index 2466455f..ef0de249 100644 --- a/src/_assert.h +++ b/src/_assert.h @@ -1,59 +1 @@ -#ifndef ___ASSERT_H__ -#define ___ASSERT_H__ - -#include -#include -#include "stdlib/_stdlib.h" - -#ifdef THREADS -_Thread_local -#endif -extern struct __checked_call { - char *file; - char *func; - unsigned long long line; -} __checked_call; - -#ifndef NDEBUG -#define ASSERT_NONNULL(__ptr) do { \ - if (!__ptr) { \ - struct __constraint_info _ci = {0}; \ - _ci.func = __func__; \ - __stdlib.constraint_handler("Undefined behavior: " \ - "Parameter " #__ptr " can not be NULL", &_ci, 0 /* was EFAULT */); \ - } \ -} while (0) - -#define ASSERT_NONZERO(__n) do { \ - if (!__n) { \ - struct __constraint_info _ci = {0}; \ - _ci.func = __func__; \ - __stdlib.constraint_handler("Undefined behavior: " \ - "Parameter " #__n " can not be 0", &_ci, ERANGE); \ - } \ -} while (0) - -#define ASSERT_NOOVERLAP(__x, __y, __s) do { \ - /* TODO */ \ -} while (0) - -#define ASSERT_REPRESENTABLE(_n, _min, _max, _type, _sentinel) do { \ - if (!(((_n) == (_sentinel)) || (((_min) <= (_n)) && ((_n) <= (_max))))) { \ - struct __constraint_info _ci = {0}; \ - _ci.func = __func__; \ - _ci.value = _n; \ - __stdlib.constraint_handler("Undefined behavior: " \ - "Parameter " #_n " must be representable as a " #_type \ - " or be equal to " #_sentinel, &_ci, ERANGE); \ - } \ - } while (0) -#else - -#define ASSERT_REPRESENTABLE(_n, _min, _max, _type, _sentinel) -#define ASSERT_NOOVERLAP(__x, __y, __s) -#define ASSERT_NONNULL(x) -#define ASSERT_NONZERO(n) - -#endif - -#endif +#include "_safety.h" diff --git a/src/_safety.h b/src/_safety.h new file mode 100644 index 00000000..5fd70493 --- /dev/null +++ b/src/_safety.h @@ -0,0 +1,71 @@ +#ifndef ___ASSERT_H__ +#define ___ASSERT_H__ + +#include +#include +#include "stdlib/_stdlib.h" +#include "signal/_signal.h" + +#if 0 +_Thread_local +#endif +extern struct __checked_call { + char *file; + char *func; + unsigned long long line; +} __checked_call; + +#ifndef NDEBUG +#define ASSERT_NONNULL(__ptr) do { \ + if (!__ptr) { \ + struct __constraint_info _ci = {0}; \ + _ci.func = __func__; \ + __stdlib.constraint_handler("Undefined behavior: " \ + "Parameter " #__ptr " can not be NULL", &_ci, 0 /* was EFAULT */); \ + } \ +} while (0) + +#define ASSERT_NONZERO(__n) do { \ + if (!__n) { \ + struct __constraint_info _ci = {0}; \ + _ci.func = __func__; \ + __stdlib.constraint_handler("Undefined behavior: " \ + "Parameter " #__n " can not be 0", &_ci, ERANGE); \ + } \ +} while (0) + +#define ASSERT_NOOVERLAP(__x, __y, __s) do { \ + /* TODO */ \ +} while (0) + +#define ASSERT_REPRESENTABLE(_n, _min, _max, _type, _sentinel) do { \ + if (!(((_n) == (_sentinel)) || (((_min) <= (_n)) && ((_n) <= (_max))))) { \ + struct __constraint_info _ci = {0}; \ + _ci.func = __func__; \ + _ci.value = _n; \ + __stdlib.constraint_handler("Undefined behavior: " \ + "Parameter " #_n " must be representable as a " #_type \ + " or be equal to " #_sentinel, &_ci, ERANGE); \ + } \ + } while (0) + +#define SIGNAL_SAFE(__n) do { \ + if (__n == 0 && __signal.current != 0) { \ + struct __constraint_info _ci = {0}; \ + _ci.func = __func__; \ + _ci.value = __signal.current; \ + __stdlib.constraint_handler("Undefined behavior: " \ + "Standard library function called from signal handler", \ + &_ci, 0); \ + } \ +} while (0) +#else + +#define ASSERT_REPRESENTABLE(_n, _min, _max, _type, _sentinel) +#define ASSERT_NOOVERLAP(__x, __y, __s) +#define ASSERT_NONNULL(x) +#define ASSERT_NONZERO(n) + +#endif + +#endif diff --git a/src/signal/__signal.c b/src/signal/__signal.c new file mode 100644 index 00000000..1c212bd1 --- /dev/null +++ b/src/signal/__signal.c @@ -0,0 +1,3 @@ +#include "_signal.h" + +struct __signal __signal = {0}; diff --git a/src/signal/_signal.h b/src/signal/_signal.h new file mode 100644 index 00000000..d699834c --- /dev/null +++ b/src/signal/_signal.h @@ -0,0 +1,8 @@ +#ifndef SIGNAL__SIGNAL_H +#define SIGNAL__SIGNAL_H + +extern struct __signal { + int current; +} __signal; + +#endif -- cgit v1.2.1