]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - ncurses/tinfo/obsolete.c
ncurses 6.4 - patch 20230624
[ncurses.git] / ncurses / tinfo / obsolete.c
index 972a9a180e78068827b5a7a607a3fb36659db7b7..e63f8a868742d4449ff83724806ade743b5c8586 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright 2020 Thomas E. Dickey                                          *
+ * Copyright 2020,2023 Thomas E. Dickey                                     *
  * Copyright 2013-2014,2016 Free Software Foundation, Inc.                  *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
@@ -37,7 +37,7 @@
 
 #include <curses.priv.h>
 
-MODULE_ID("$Id: obsolete.c,v 1.6 2020/02/02 23:34:34 tom Exp $")
+MODULE_ID("$Id: obsolete.c,v 1.9 2023/06/24 22:02:25 tom Exp $")
 
 /*
  * Obsolete entrypoint retained for binary compatibility.
@@ -238,3 +238,94 @@ _nc_conv_to_utf32(unsigned *target, const char *source, unsigned limit)
 #undef CH
 }
 #endif /* EXP_XTERM_1005 */
+
+#ifdef EXP_OOM_TESTING
+/*
+ * Out-of-memory testing, suitable for checking if initialization (and limited
+ * running) recovers from errors due to insufficient memory.  In practice, this
+ * is unlikely except with artifically constructed tests (or poorly behaved
+ * applications).
+ */
+#undef malloc
+#undef calloc
+#undef realloc
+#undef free
+#undef strdup
+
+static long oom_limit = -1;
+static long oom_count = 0;
+
+static bool
+oom_check(void)
+{
+    static bool initialized = FALSE;
+    static bool triggered = FALSE;
+    bool result = FALSE;
+
+    if (!initialized) {
+       char *env = getenv("NCURSES_OOM_TESTING");
+       initialized = TRUE;
+       if (env != NULL) {
+           char *check;
+           oom_limit = strtol(env, &check, 0);
+           if (check != NULL && *check != '\0')
+               oom_limit = 0;
+       }
+    }
+    if (oom_limit >= 0) {
+       result = (++oom_count > oom_limit);
+       if (result && !triggered) {
+           triggered = TRUE;
+           T(("out-of-memory"));
+       }
+    }
+    return result;
+}
+
+NCURSES_EXPORT(void *)
+_nc_oom_malloc(size_t size)
+{
+    char *result = (oom_check()
+                   ? NULL
+                   : malloc(size));
+    T(("oom #%ld malloc(%ld) %p", oom_count, size, result));
+    return result;
+}
+
+NCURSES_EXPORT(void *)
+_nc_oom_calloc(size_t nmemb, size_t size)
+{
+    char *result = (oom_check()
+                   ? NULL
+                   : calloc(nmemb, size));
+    T(("oom #%ld calloc(%ld, %ld) %p", oom_count, nmemb, size, result));
+    return result;
+}
+
+NCURSES_EXPORT(void *)
+_nc_oom_realloc(void *ptr, size_t size)
+{
+    char *result = (oom_check()
+                   ? NULL
+                   : realloc(ptr, size));
+    T(("oom #%ld realloc(%p, %ld) %p", oom_count, ptr, size, result));
+    return result;
+}
+
+NCURSES_EXPORT(void)
+_nc_oom_free(void *ptr)
+{
+    T(("oom #%ld free(%p)", oom_count, ptr));
+    free(ptr);
+}
+
+NCURSES_EXPORT(char *)
+_nc_oom_strdup(const char *ptr)
+{
+    char *result = (oom_check()
+                   ? NULL
+                   : strdup(ptr));
+    T(("oom #%ld strdup(%p) %p", oom_count, ptr, result));
+    return result;
+}
+#endif /* EXP_OOM_TESTING */