#include #include #ifndef NO_UNISTD_H #include #endif /* A simple glue file for embedded targets so we can get the real exit status from the program. This assumes we're using GNU ld and can use the -wrap option, and that write(1, ...) does something useful. */ /* There is a bunch of weird cruft with #ifdef UNDERSCORES. This is needed because currently GNU ld doesn't deal well with a.out targets and the -wrap option. When GNU ld is fixed, this should definitely be removed. Note that we actually wrap __exit, not _exit on a target that has UNDERSCORES defined. On non-UNDERSCORE targets, we wrap _exit separately; it's actually a different function. */ #ifdef WRAP_M68K_AOUT #define REAL_EXIT(code) asm ( "trap %0" : : "i" (0) ); #define REAL_ABORT() REAL_EXIT(6) #define ORIG_EXIT _exit #define ORIG_ABORT abort #else #ifdef UNDERSCORES #define REAL_EXIT _real___exit #define REAL_MAIN _real__main #define REAL_ABORT _real__abort #define ORIG_EXIT _wrap___exit #define ORIG_ABORT _wrap__abort #define ORIG_MAIN _wrap__main #else #define REAL_EXIT __real_exit #ifndef VXWORKS #define REAL__EXIT __real__exit #endif #define REAL_MAIN __real_main #define REAL_ABORT __real_abort #define ORIG_EXIT __wrap_exit #define ORIG__EXIT __wrap__exit #define ORIG_ABORT __wrap_abort #define ORIG_MAIN __wrap_main #endif extern void abort (void); extern void exit (int); #endif #ifdef REAL_MAIN extern void REAL_EXIT (); extern void REAL_ABORT (); extern int REAL_MAIN (int argc, char **argv, char **envp); #endif #ifdef REAL__EXIT extern void REAL__EXIT (); #endif static int done_exit_message = 0; int ___constval = 1; #ifdef VXWORKS static void __runexit(); #endif static char * write_int(val, ptr) int val; char *ptr; { char c; if (val<0) { *(ptr++) = '-'; val = -val; } if (val>9) { ptr = write_int (val/10, ptr); } c = (val%10)+'0'; *(ptr++) = c; return ptr; } void ORIG_EXIT (code) int code; { char buf[30]; char *ptr; #ifdef VXWORKS __runexit (); #endif strcpy (buf, "\n*** EXIT code "); ptr = write_int (code, buf + strlen(buf)); *(ptr++) = '\n'; write (1, buf, ptr-buf); done_exit_message = 1; REAL_EXIT (code); while (___constval); } #ifdef ORIG__EXIT void ORIG__EXIT (code) int code; { char buf[30]; char *ptr; /* Since exit may call _exit, we need to avoid a second message. */ if (! done_exit_message) { strcpy (buf, "\n*** EXIT code "); ptr = write_int (code, buf + strlen(buf)); *(ptr++) = '\n'; write (1, buf, ptr-buf); } REAL__EXIT (code); while (___constval); } #endif void ORIG_ABORT () { write (1, "\n*** EXIT code 4242\n", 20); REAL_ABORT (); while (___constval); abort (); } #ifdef REAL_MAIN int ORIG_MAIN (argc, argv, envp) int argc; char **argv; char **envp; { #ifdef WRAP_FILE_ARGS extern int __argc; extern char *__args[]; exit (REAL_MAIN (__argc,__args,envp)); #else exit (REAL_MAIN (argc, argv, envp)); #endif while (___constval); } #endif #ifdef VXWORKS void _exit (status) int status; { REAL_EXIT (status); } typedef (*PFV)(void); static PFV __list[32]; static int __listcnt = 0; static int __running = 0; int atexit (PFV func) { __list[__listcnt++] = func; } static void __runexit () { int i; if (__running++) return; for (i = 0; i < __listcnt; i++) __list[i](); __running = 0; } #endif