int run(char* process_name){ int i; for (i=0; i<NR_TASKS; i++) if (proc_table[i].status!=STOPPED){ if (strcmp(proc_table[i].p_name,process_name)==0){ if (proc_table[i].status==RUNNING) return -1; restart_process(process_name); return proc_table[i].pid; } } FILEINFO file; memset(&file,0,sizeof(file)); if (get_file_info_by_name(process_name,&file)!=-1){ return start_program(process_name,(void *)file.start_pos); } else{ for (i=0; i<NR_INNERPROCESS; i++) if (strcmp(IN_PROCESS[i].name,process_name)==0){ return start_program(process_name,IN_PROCESS[i].initial_eip); } } return -1; }
int main(int argc, char** argv) #endif { #ifdef HAVE_VISUAL_LEAK_DETECTOR VLDEnable(); #endif #ifdef _WIN32 (void)argc; (void)argv; //windows argv is ansi encoded by default std::vector<std::string> args = parse_commandline_arguments(unicode_cast<std::string>(std::wstring(GetCommandLineW()))); // HACK: we don't parse command line arguments using program_options until // the startup banner is printed. We need to get a console up and // running before then if requested, so just perform a trivial search // here and let program_options ignore the switch later. for(size_t k = 0; k < args.size(); ++k) { if(args[k] == "--wconsole" || args[k] == "--help" || args[k] == "--nogui" || args[k] == "--logdomains" || args[k] == "--path" || args[k] == "--render-image" || args[k] == "--screenshot" || args[k] == "--data-path" || args[k] == "--userdata-path" || args[k] == "--userconfig-path" || args[k] == "--version") { lg::enable_native_console_output(); break; } } lg::early_log_file_setup(); #else std::vector<std::string> args; for(int i = 0; i < argc; ++i) { args.push_back(std::string(argv[i])); } #endif assert(!args.empty()); #ifdef _OPENMP // Wesnoth is a special case for OMP // OMP wait strategy is to have threads busy-loop for 100ms // if there is nothing to do, they then go to sleep. // this avoids the scheduler putting the thread to sleep when work // is about to be available // // However Wesnoth has a lot of very small jobs that need to be done // at each redraw => 50fps every 2ms. // All the threads are thus busy-waiting all the time, hogging the CPU // To avoid that problem, we need to set the OMP_WAIT_POLICY env var // but that var is read by OMP at library loading time (before main) // thus the relaunching of ourselves after setting the variable. #if !defined(_WIN32) && !defined(__APPLE__) if (!getenv("OMP_WAIT_POLICY")) { setenv("OMP_WAIT_POLICY", "PASSIVE", 1); execv(argv[0], argv); } #elif _MSC_VER >= 1600 if (!getenv("OMP_WAIT_POLICY")) { _putenv_s("OMP_WAIT_POLICY", "PASSIVE"); args[0] = utils::quote(args[0]); restart_process(args); } #endif #endif //_OPENMP if(SDL_Init(SDL_INIT_TIMER) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); return(1); } #ifndef _WIN32 struct sigaction terminate_handler; terminate_handler.sa_handler = wesnoth_terminate_handler; terminate_handler.sa_flags = 0; sigemptyset(&terminate_handler.sa_mask); sigaction(SIGTERM, &terminate_handler, nullptr); sigaction(SIGINT, &terminate_handler, nullptr); #endif //declare this here so that it will always be at the front of the event queue. events::event_context global_context; try { std::cerr << "Battle for Wesnoth v" << game_config::revision << '\n'; const time_t t = time(nullptr); std::cerr << "Started on " << ctime(&t) << "\n"; const std::string& exe_dir = filesystem::get_exe_dir(); if(!exe_dir.empty()) { // Try to autodetect the location of the game data dir. Note that // the root of the source tree currently doubles as the data dir. std::string auto_dir; // scons leaves the resulting binaries at the root of the source // tree by default. if(filesystem::file_exists(exe_dir + "/data/_main.cfg")) { auto_dir = exe_dir; } // cmake encourages creating a subdir at the root of the source // tree for the build, and the resulting binaries are found in it. else if(filesystem::file_exists(exe_dir + "/../data/_main.cfg")) { auto_dir = filesystem::normalize_path(exe_dir + "/.."); } // In Windows debug builds, the EXE is placed away from the game data dir // (in projectfiles\VCx\Debug), but the working directory is set to the // game data dir. Thus, check if the working dir is the game data dir. else if(filesystem::file_exists(filesystem::get_cwd() + "/data/_main.cfg")) { auto_dir = filesystem::get_cwd(); } if(!auto_dir.empty()) { std::cerr << "Automatically found a possible data directory at " << auto_dir << '\n'; game_config::path = auto_dir; } } const int res = do_gameloop(args); safe_exit(res); } catch(boost::program_options::error& e) { std::cerr << "Error in command line: " << e.what() << '\n'; return 1; } catch(CVideo::error&) { std::cerr << "Could not initialize video. Exiting.\n"; return 1; } catch(font::manager::error&) { std::cerr << "Could not initialize fonts. Exiting.\n"; return 1; } catch(config::error& e) { std::cerr << e.message << "\n"; return 1; } catch(gui::button::error&) { std::cerr << "Could not create button: Image could not be found\n"; return 1; } catch(CVideo::quit&) { //just means the game should quit } catch(return_to_play_side_exception&) { std::cerr << "caught return_to_play_side_exception, please report this bug (quitting)\n"; } catch(quit_game_exception&) { std::cerr << "caught quit_game_exception (quitting)\n"; } catch(twml_exception& e) { std::cerr << "WML exception:\nUser message: " << e.user_message << "\nDev message: " << e.dev_message << '\n'; return 1; } catch(game_logic::formula_error& e) { std::cerr << e.what() << "\n\nGame will be aborted.\n"; return 1; } catch(const sdl::texception& e) { std::cerr << e.what(); return 1; } catch(game::error &) { // A message has already been displayed. return 1; } catch(std::bad_alloc&) { std::cerr << "Ran out of memory. Aborted.\n"; return ENOMEM; #if !defined(NO_CATCH_AT_GAME_END) } catch(std::exception & e) { // Try to catch unexpected exceptions. std::cerr << "Caught general exception:\n" << e.what() << std::endl; return 1; } catch(std::string & e) { std::cerr << "Caught a string thrown as an exception:\n" << e << std::endl; return 1; } catch(const char * e) { std::cerr << "Caught a string thrown as an exception:\n" << e << std::endl; return 1; } catch(...) { // Ensure that even when we terminate with `throw 42`, the exception // is caught and all destructors are actually called. (Apparently, // some compilers will simply terminate without calling destructors if // the exception isn't caught.) std::cerr << "Caught unspecified general exception. Terminating." << std::endl; return 1; #endif } return 0; } // end main