diff --git a/src/engine/builtins.cpp b/src/engine/builtins.cpp index 54745bd3c..c61e77a4f 100644 --- a/src/engine/builtins.cpp +++ b/src/engine/builtins.cpp @@ -24,6 +24,7 @@ #include "pathsys.h" #include "rules.h" #include "jam_strings.h" +#include "startup.h" #include "subst.h" #include "timestamp.h" #include "variable.h" @@ -650,10 +651,10 @@ LIST * builtin_exit( FRAME * frame, int flags ) break; } #endif - exit( status ); + b2::clean_exit( status ); } else - exit( EXITBAD ); /* yeech */ + b2::clean_exit( EXITBAD ); /* yeech */ return L0; } @@ -1176,7 +1177,7 @@ void unknown_rule( FRAME * frame, char const * key, module_t * module, else out_printf( "root module.\n" ); backtrace( frame->prev ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } @@ -1258,7 +1259,7 @@ LIST * builtin_import( FRAME * frame, int flags ) list_print( target_rules ); out_printf( "\n" ); backtrace( frame->prev ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } return L0; @@ -1633,7 +1634,7 @@ LIST * builtin_native_rule( FRAME * frame, int flags ) out_printf( "error: no native rule \"%s\" defined in module \"%s.\"\n", object_str( list_front( rule_name ) ), object_str( module->name ) ); backtrace( frame->prev ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } return L0; } diff --git a/src/engine/class.cpp b/src/engine/class.cpp index 2928ff7cb..09084c892 100644 --- a/src/engine/class.cpp +++ b/src/engine/class.cpp @@ -16,6 +16,7 @@ #include "jam_strings.h" #include "variable.h" #include "output.h" +#include "startup.h" #include #include @@ -34,7 +35,7 @@ static void check_defined( LIST * class_names ) { out_printf( "Class %s is not defined\n", object_str( list_item( iter ) ) ); - abort(); + b2::clean_exit( b2::exit_result::failure ); } } } @@ -143,7 +144,7 @@ OBJECT * make_class_module( LIST * xname, LIST * bases, FRAME * frame ) { out_printf( "Class %s already defined\n", object_str( list_front( xname ) ) ); - abort(); + b2::clean_exit( b2::exit_result::failure ); } check_defined( bases ); diff --git a/src/engine/cwd.cpp b/src/engine/cwd.cpp index 29dbf3f55..f216e7151 100644 --- a/src/engine/cwd.cpp +++ b/src/engine/cwd.cpp @@ -12,6 +12,7 @@ #include "mem.h" #include "output.h" #include "pathsys.h" +#include "startup.h" #include #include @@ -74,7 +75,7 @@ void cwd_init( void ) if ( !cwd_ ) { errno_puts( "can not get current working directory" ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } } diff --git a/src/engine/execnt.cpp b/src/engine/execnt.cpp index d0000d282..443e69aa8 100644 --- a/src/engine/execnt.cpp +++ b/src/engine/execnt.cpp @@ -46,6 +46,7 @@ #include "lists.h" #include "output.h" #include "pathsys.h" +#include "startup.h" #include "string.h" #include @@ -1270,7 +1271,7 @@ static char const * prepare_command_file( string const * command, int32_t slot ) if ( !f ) { err_printf( "failed to write command file!\n" ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } fputs( command->value, f ); fclose( f ); @@ -1289,7 +1290,7 @@ static int32_t get_free_cmdtab_slot() if ( !cmdtab[ slot ].pi.hProcess ) return slot; err_printf( "no slots for child!\n" ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } diff --git a/src/engine/execunix.cpp b/src/engine/execunix.cpp index f1ca14fd8..7825fffe7 100644 --- a/src/engine/execunix.cpp +++ b/src/engine/execunix.cpp @@ -14,6 +14,7 @@ #include "lists.h" #include "output.h" #include "jam_strings.h" +#include "startup.h" #include #include @@ -216,7 +217,7 @@ void exec_cmd if ( pipe( out ) < 0 || ( globs.pipe_action && pipe( err ) < 0 ) ) { errno_puts( "pipe" ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } /* Start the command */ @@ -258,7 +259,7 @@ void exec_cmd if ( ( cmdtab[ slot ].pid = vfork() ) == -1 ) { errno_puts( "vfork" ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } if ( cmdtab[ slot ].pid == 0 ) @@ -295,7 +296,7 @@ void exec_cmd } if (0 != setpgid( pid, pid )) { errno_puts("setpgid(child)"); - /* exit( EXITBAD ); */ + /* b2::clean_exit( EXITBAD ); */ } execvp( argv[ 0 ], (char * *)argv ); errno_puts( "execvp" ); @@ -325,7 +326,7 @@ void exec_cmd if ( !cmdtab[ slot ].stream[ OUT ] ) { errno_puts( "fdopen" ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } /* Parent reads from err[ EXECCMD_PIPE_READ ]. */ @@ -336,7 +337,7 @@ void exec_cmd if ( !cmdtab[ slot ].stream[ ERR ] ) { errno_puts( "fdopen" ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } } @@ -542,7 +543,7 @@ void exec_wait() if ( pid != cmdtab[ i ].pid ) { err_printf( "unknown pid %d with errno = %d\n", pid, errno ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } /* Set reason for exit if not timed out. */ @@ -601,7 +602,8 @@ static int get_free_cmdtab_slot() if ( !cmdtab[ slot ].pid ) return slot; err_printf( "no slots for child!\n" ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); + return -1; } int32_t shell_maxline() diff --git a/src/engine/execvms.cpp b/src/engine/execvms.cpp index 7a70b365f..05b6c7a20 100644 --- a/src/engine/execvms.cpp +++ b/src/engine/execvms.cpp @@ -35,6 +35,7 @@ #include "lists.h" #include "execcmd.h" #include "output.h" +#include "startup.h" #ifdef OS_VMS @@ -201,7 +202,7 @@ void exec_cmd if ( !cwd ) { errno_puts( "can not get current working directory" ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } fprintf( f, "$ SET DEFAULT %s\n", cwd); diff --git a/src/engine/function.cpp b/src/engine/function.cpp index f80f4977a..2db31cfae 100644 --- a/src/engine/function.cpp +++ b/src/engine/function.cpp @@ -23,6 +23,7 @@ #include "search.h" #include "variable.h" #include "output.h" +#include "startup.h" #include #include @@ -480,7 +481,7 @@ static LIST * function_call_rule( JAM_FUNCTION * function, FRAME * frame, { out_printf( "ERROR: rules are limited to %d arguments\n", LOL_MAX ); backtrace( inner ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } for ( i = 0; i < n_args; ++i ) @@ -580,7 +581,7 @@ static LIST * function_call_member_rule( JAM_FUNCTION * function, FRAME * frame, { out_printf( "ERROR: member rules are limited to %d arguments\n", LOL_MAX ); backtrace( inner ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } for( i = 0; i < n_args; ++i ) @@ -3215,7 +3216,7 @@ static void argument_error( char const * message, FUNCTION * procedure, print_source_line( frame ); out_printf( "see definition of rule '%s' being called\n", frame->rulename ); backtrace( frame->prev ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } static void type_check_range( OBJECT * type_name, LISTITER iter, LISTITER end, @@ -3505,7 +3506,7 @@ static void argument_compiler_add( struct argument_compiler * c, OBJECT * arg, { err_printf( "%s:%d: missing argument name before type name: %s\n", object_str( file ), line, object_str( arg ) ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } c->arg.arg_name = object_copy( arg ); @@ -3553,7 +3554,7 @@ static struct arg_list arg_compile_impl( struct argument_compiler * c, case ARGUMENT_COMPILER_FOUND_TYPE: err_printf( "%s:%d: missing argument name after type name: %s\n", object_str( file ), line, object_str( c->arg.type_name ) ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); case ARGUMENT_COMPILER_FOUND_OBJECT: dynamic_array_push( c->args, c->arg ); break; @@ -4134,7 +4135,7 @@ LIST * function_execute_write_file( { err_printf( "[errno %d] failed to write output file '%s': %s", errno, out_name->value, strerror(errno) ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } string_free( out_name ); } diff --git a/src/engine/jam.cpp b/src/engine/jam.cpp index a74786b46..5c3baff7c 100644 --- a/src/engine/jam.cpp +++ b/src/engine/jam.cpp @@ -242,10 +242,10 @@ static void usage( const char * progname ) #endif err_printf("--x Option is ignored.\n\n"); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } -int main( int argc, char * * argv ) +int guarded_main( int argc, char * * argv ) { int n; char * s; @@ -261,15 +261,6 @@ int main( int argc, char * * argv ) saved_argv0 = argv[ 0 ]; last_update_now_status = 0; - BJAM_MEM_INIT(); - -#ifdef OS_MAC - InitGraf( &qd.thePort ); -#endif - - cwd_init(); - constants_init(); - #ifdef JAM_DEBUGGER is_debugger = 0; @@ -382,7 +373,7 @@ int main( int argc, char * * argv ) { err_printf( "Invalid pipe descriptor '%d', valid values are -p[0..3]." "\n", globs.pipe_action ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } } @@ -398,7 +389,7 @@ int main( int argc, char * * argv ) if ( globs.jobs < 1 ) { err_printf( "Invalid value for the '-j' option.\n" ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } } @@ -449,7 +440,7 @@ int main( int argc, char * * argv ) { err_printf( "[errno %d] failed to write output file '%s': %s", errno, s, strerror(errno) ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } /* ++globs.noexec; */ } @@ -668,10 +659,33 @@ int main( int argc, char * * argv ) PROFILE_EXIT( MAIN ); } + return status ? EXITBAD : EXITOK; +} + +int main( int argc, char * * argv ) +{ + BJAM_MEM_INIT(); + +#ifdef OS_MAC + InitGraf( &qd.thePort ); +#endif + + cwd_init(); + constants_init(); + + int result = EXIT_SUCCESS; + try + { + result = guarded_main( argc, argv ); + } + catch ( b2::exit_result exit_code ) + { + result = (int)exit_code; + } + if ( DEBUG_PROFILE ) profile_dump(); - #ifdef OPT_HEADER_CACHE_EXT hcache_done(); #endif @@ -705,5 +719,5 @@ int main( int argc, char * * argv ) BJAM_MEM_CLOSE(); - return status ? EXITBAD : EXITOK; + return result; } diff --git a/src/engine/make1.cpp b/src/engine/make1.cpp index 9f744b4cb..332b91cc5 100644 --- a/src/engine/make1.cpp +++ b/src/engine/make1.cpp @@ -51,6 +51,7 @@ #include "search.h" #include "variable.h" #include "output.h" +#include "startup.h" #include #include @@ -257,7 +258,7 @@ int32_t make1( LIST * targets ) /* If we were interrupted, exit now that all child processes have finished. */ if ( intr ) - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); { LISTITER iter, end; @@ -478,7 +479,7 @@ static void make1b( state * const pState ) default: err_printf( "ERROR: %s has bad fate %d", object_str( t->name ), t->fate ); - abort(); + b2::clean_exit( b2::exit_result::failure ); } /* Proceed to MAKE1C to begin executing the chain of commands prepared for @@ -1225,7 +1226,7 @@ static CMD * make1cmds( TARGET * t ) /* Tell the user what did not fit. */ out_puts( cmd->buf->value ); - exit( EXITBAD ); + b2::clean_exit( EXITBAD ); } assert( !retry || !accept_command );