X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Fobsolete.c;h=972a9a180e78068827b5a7a607a3fb36659db7b7;hp=2724fe53486a502492e710faa5536ab9d5046629;hb=HEAD;hpb=e2e9c09c48b19b24979cafb2d4864f538b5ddd1c diff --git a/ncurses/tinfo/obsolete.c b/ncurses/tinfo/obsolete.c index 2724fe53..cc62f18c 100644 --- a/ncurses/tinfo/obsolete.c +++ b/ncurses/tinfo/obsolete.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 2013-2014,2016 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,10 +37,10 @@ #include -MODULE_ID("$Id: obsolete.c,v 1.4 2016/09/10 18:39:51 tom Exp $") +MODULE_ID("$Id: obsolete.c,v 1.11 2023/10/21 15:38:47 tom Exp $") /* - * Obsolete entrypoint retained for binary compatbility. + * Obsolete entrypoint retained for binary compatibility. */ NCURSES_EXPORT(void) NCURSES_SP_NAME(_nc_set_buffer) (NCURSES_SP_DCLx FILE *ofp, int buffered) @@ -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 artificially 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 */