X-Git-Url: https://ncurses.scripts.mit.edu/?a=blobdiff_plain;f=ncurses%2Ftinfo%2Fobsolete.c;h=869496c28f1d0e2caa26d0b56f69a7f93ecab264;hb=d1a029866f6d84087781eaa81de19949d8533426;hp=37f9de34b14720454fad3d71f6f2b7ef32eb20db;hpb=c55d387cebf1cee4757ca2c2ef4fbeae59ee4175;p=ncurses.git diff --git a/ncurses/tinfo/obsolete.c b/ncurses/tinfo/obsolete.c index 37f9de34..869496c2 100644 --- a/ncurses/tinfo/obsolete.c +++ b/ncurses/tinfo/obsolete.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 2013-2016,2020 Free Software Foundation, Inc. * + * 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 * * copy of this software and associated documentation files (the * @@ -36,7 +37,7 @@ #include -MODULE_ID("$Id: obsolete.c,v 1.5 2020/01/18 17:02:38 tom Exp $") +MODULE_ID("$Id: obsolete.c,v 1.10 2023/06/25 16:56:27 tom Exp $") /* * Obsolete entrypoint retained for binary compatibility. @@ -237,3 +238,98 @@ _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 + +#define TR_OOM(stmt) T(stmt) + +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; + } + } + ++oom_count; + if (oom_limit >= 0) { + result = (oom_count > oom_limit); + if (result && !triggered) { + triggered = TRUE; + TR_OOM(("out-of-memory")); + } + } + return result; +} + +NCURSES_EXPORT(void *) +_nc_oom_malloc(size_t size) +{ + char *result = (oom_check() + ? NULL + : malloc(size)); + TR_OOM(("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)); + TR_OOM(("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)); + TR_OOM(("oom #%ld realloc(%p, %ld) %p", oom_count, ptr, size, result)); + return result; +} + +NCURSES_EXPORT(void) +_nc_oom_free(void *ptr) +{ + ++oom_count; + TR_OOM(("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)); + TR_OOM(("oom #%ld strdup(%p) %p", oom_count, ptr, result)); + return result; +} +#endif /* EXP_OOM_TESTING */