// // Cforall Version 1.0.0 Copyright (C) 2022 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // fork+exec.cfa -- Check that we can use fork+exec to test parameters. // // Author : Thierry Delisle // Created On : Wed Sep 27 10:44:38 2022 // Last Modified By : // Last Modified On : // Update Count : // #include #include #include #include #include extern "C" { #include #include #include } int true_main(const char * exec); int main(int argc, char * argv[]) { if(!getenv("CFATEST_FORK_EXEC_TEXT")) return true_main(argv[0]); printf("arguments are:\n"); if(argc == 1) printf(" None\n"); for(int i = 1; i < argc; i++) { printf(" '%s'\n", argv[i]); } printf("Success!\n"); fflush(stdout); return 0; } int do_wait(pid_t pid) { int wstatus; int options = 0; pid_t ret = waitpid(pid, &wstatus, options); fflush(stdout); if(ret < 0) { fprintf(stderr, "Fork returned with error: %d '%s'\n", errno, strerror(errno)); exit(1); } return wstatus; } pid_t strict_fork(void) { fflush(stdout); pid_t ret = fork(); if(ret < 0) { fprintf(stderr, "Fork returned with error: %d '%s'\n", errno, strerror(errno)); exit(1); } return ret; } void print_status(int wstatus) { printf("Child status:\n"); printf(" WIFEXITED : %d\n", WIFEXITED(wstatus)); printf(" WEXITSTATUS : %d\n", WEXITSTATUS(wstatus)); printf(" WIFSIGNALED : %d\n", WIFSIGNALED(wstatus)); printf(" WTERMSIG : %d\n", WTERMSIG(wstatus)); printf(" WCOREDUMP : %d\n", WCOREDUMP(wstatus)); printf(" WIFSTOPPED : %d\n", WIFSTOPPED(wstatus)); printf(" WSTOPSIG : %d\n", WSTOPSIG(wstatus)); printf(" WIFCONTINUED: %d\n", WIFCONTINUED(wstatus)); } int true_main(const char * path) { char * env[] = { "CFATEST_FORK_EXEC_TEXT=1", 0p }; printf("no arg:\n"); if(pid_t child = strict_fork(); child == 0) { int ret = execle(path, path, (const char*)0p, env); if(ret < 0) { fprintf(stderr, "Execl 1 returned with error: %d '%s'\n", errno, strerror(errno)); exit(1); } } else { int status = do_wait(child); print_status(status); } printf("1 arg:\n"); if(pid_t child = strict_fork(); child == 0) { int ret = execle(path, path, "Hello World!", (const char*)0p, env); if(ret < 0) { fprintf(stderr, "Execl 2 returned with error: %d '%s'\n", errno, strerror(errno)); exit(1); } } else { int status = do_wait(child); print_status(status); } printf("5 arg:\n"); if(pid_t child = strict_fork(); child == 0) { int ret = execle(path, path, "Hi,", "my", "name", "is", "Fred", (const char*)0p, env); if(ret < 0) { fprintf(stderr, "Execl 3 returned with error: %d '%s'\n", errno, strerror(errno)); exit(1); } } else { int status = do_wait(child); print_status(status); } printf("All Done!\n"); return 0; }