Add DOH Exit() and SetExitHandler()
Exit() is a wrapper for exit() by default, but SetExitHandler() allows specifying a function to call instead. This means that failures within DOH (e.g. Malloc() failing due to lack of memory) will now perform cleanup such as removing output files. This commit also cleans up exit statuses so SWIG should now reliably exit with status 0 if the run was successful and status 1 if there was an error (or a warning and -Werror was in effect). Previously in some situations SWIG would try to exit with the status set to the number of errors encountered, but that's problematic - for example if there were 256 errors this would result in exit status 0 on most platforms. Also some error statuses have special meanings e.g. those defined by <sysexits.h>. Also SWIG/Javascript tried to exit with status -1 in a few places (which typically results in exit status 255).
This commit is contained in:
parent
7bdef23304
commit
55377bdc08
33 changed files with 243 additions and 173 deletions
|
|
@ -126,6 +126,8 @@
|
|||
#define DohRealloc DOH_NAMESPACE(Realloc)
|
||||
#define DohCalloc DOH_NAMESPACE(Calloc)
|
||||
#define DohFree DOH_NAMESPACE(Free)
|
||||
#define DohSetExitHandler DOH_NAMESPACE(SetExitHandler)
|
||||
#define DohExit DOH_NAMESPACE(Exit)
|
||||
#endif
|
||||
|
||||
#define DOH_MAJOR_VERSION 0
|
||||
|
|
@ -274,6 +276,24 @@ extern int DohGetMaxHashExpand(void);
|
|||
extern void DohSetmark(DOH *obj, int x);
|
||||
extern int DohGetmark(DOH *obj);
|
||||
|
||||
/* Set the function for DohExit() to call instead of exit().
|
||||
*
|
||||
* The registered function can perform clean up, etc and then should call
|
||||
* exit(status) to end the process. Bear in mind that this can be called
|
||||
* after malloc() has failed, so avoiding allocating additional memory in
|
||||
* the registered function is a good idea.
|
||||
*
|
||||
* The registered function is unregistered by DohExit() before calling it to
|
||||
* avoid the potential for infinite loops.
|
||||
*
|
||||
* Note: This is sort of like C's atexit(), only for DohExit(). However
|
||||
* only one function can be registered (setting a new function overrides the
|
||||
* previous one) and the registered function is passed the exit status and
|
||||
* should itself call exit().
|
||||
*/
|
||||
extern void DohSetExitHandler(void (*new_handler)(int));
|
||||
extern void DohExit(int status);
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Strings.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
@ -447,6 +467,8 @@ extern void DohMemoryDebug(void);
|
|||
#define Realloc DohRealloc
|
||||
#define Calloc DohCalloc
|
||||
#define Free DohFree
|
||||
#define SetExitHandler DohSetExitHandler
|
||||
#define Exit DohExit
|
||||
#endif
|
||||
|
||||
#ifdef NIL
|
||||
|
|
|
|||
|
|
@ -235,6 +235,26 @@ void DohMemoryDebug(void) {
|
|||
|
||||
}
|
||||
|
||||
/* Function to call instead of exit(). */
|
||||
static void (*doh_exit_handler)(int) = NULL;
|
||||
|
||||
void DohSetExitHandler(void (*new_handler)(int)) {
|
||||
doh_exit_handler = new_handler;
|
||||
}
|
||||
|
||||
void DohExit(int status) {
|
||||
if (doh_exit_handler) {
|
||||
void (*handler)(int) = doh_exit_handler;
|
||||
/* Unset the handler to avoid infinite loops if it tries to do something
|
||||
* which calls DohExit() (e.g. calling Malloc() and that failing).
|
||||
*/
|
||||
doh_exit_handler = NULL;
|
||||
handler(status);
|
||||
} else {
|
||||
exit(status);
|
||||
}
|
||||
}
|
||||
|
||||
static void allocation_failed(size_t n, size_t size) {
|
||||
/* Report and exit as directly as possible to try to avoid further issues due
|
||||
* to lack of memory. */
|
||||
|
|
@ -251,7 +271,7 @@ static void allocation_failed(size_t n, size_t size) {
|
|||
fprintf(stderr, "Failed to allocate %lu*%lu bytes\n", (unsigned long)n, (unsigned long)size);
|
||||
#endif
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
DohExit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void *DohMalloc(size_t size) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue