/* VIM: let g:lcppflags="-std=c++11 -O2 -pthread" VIM: let g:wcppflags="/O2 /EHsc /DWIN32" VIM-: let g:cppflags=g:Iboost.g:Itbb VIM-: let g:ldflags=g:Lboost.g:Ltbb.g:tbbmalloc.g:tbbmproxy VIM-: let g:ldlibpath=g:Bboost.g:Btbb VIM: let g:argv="" */ #include #include #include #include #ifndef WCOREDUMP #define WCOREDUMP(status) (0) #endif void pr_exit(int status) { if (WIFEXITED(status)) std::cout << "normal termination, exit status =" << WEXITSTATUS(status) << std::endl; else if (WIFSIGNALED(status)) std::cout << "abnormal termination, signal number = " << WTERMSIG(status) << (WCOREDUMP(status) ? " (core file generated)" : "") << std::endl; else if (WIFSTOPPED(status)) std::cout << "child stopped, signal number = " << WSTOPSIG(status) << std::endl; } template< class F> void fork_and_wait( const char * caption, F&& f ) { std::cout << caption << ": "; std::cout.flush(); pid_t pid; int status; if ((pid = fork()) < 0) throw std::runtime_error("fork error"); else if (pid == 0) /* child */ { f(); exit(0); } else/*parent*/ { if (wait(&status) != pid) /* wait for child */ throw std::runtime_error("wait error"); pr_exit(status); /* and print its status */ } } void test() { fork_and_wait("exit(7)", [](){ exit(7); }); fork_and_wait("SIGABORT through abort()", [](){ abort(); }); fork_and_wait("SIGFPE through divison by zero", [](){ int a = rand(); int b = 0; a /= b; }); } int main ( void ) {try{ test(); return 0; } catch ( const std::exception& e ) { std::cerr << std::endl << "std::exception(\"" << e.what() << "\")." << std::endl; return 2; } catch ( ... ) { std::cerr << std::endl << "unknown exception." << std::endl; return 1; }}