ATF_TC_BODY(fork_wait__signals, tc) { ATF_REQUIRE_MSG(LAST_SIGNO > 10, "LAST_SIGNO as detected by configure is " "suspiciously low"); int signo; for (signo = 1; signo <= LAST_SIGNO; signo++) { if (signo == SIGKILL || signo == SIGSTOP) { // Ignore immutable signals. continue; } if (signo == SIGCHLD) { // If we were to reset SIGCHLD to SIG_IGN (which is different than // not touching the signal at all, leaving it at its default value), // our child process will not become a zombie and the call to // kyua_run_wait will fail. Avoid this. continue; } struct sigaction sa; sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; printf("Ignoring signal %d\n", signo); ATF_REQUIRE(sigaction(signo, &sa, NULL) != -1); } ATF_REQUIRE_MSG(fork_check(NULL, check_signals, NULL), "Signals not reset to their default state"); }
int execute_cmd(char **cmd_args) { int retval = 1; int num_of_subcmds = count_subcmds(cmd_args); // cmd_mat has enough slots plus one for the null element char ***cmd_mat = calloc((size_t)num_of_subcmds + 1, sizeof(char **)); if (checkInput(cmd_args) == 0) { split_subcmds(cmd_args, cmd_mat); if (num_of_subcmds > 1) { // there was a pipe pid_t pid = fork_check(); if (pid == 0) { pipe_process(cmd_mat, num_of_subcmds - 1); } else { int status; waitpid(pid, &status, 0); } } else { // no pipes, resume as normal retval = non_pipe_process(cmd_mat); } } else { printf("Invalid command!\n"); fflush(stdout); } free(cmd_mat); return retval; }
ATF_TC_BODY(fork_wait__no_terminal, tc) { kyua_run_params_t run_params; kyua_run_params_init(&run_params); // If we fail to disconnect the subprocess from the terminal, our test // function will probably get stuck. Don't let it run for too long. run_params.timeout_seconds = 10; ATF_REQUIRE_MSG(fork_check(&run_params, check_no_terminal, NULL), "Subprocess apparently still has a terminal"); }
ATF_TC_BODY(fork_wait__work_directory, tc) { ATF_REQUIRE(mkdir("the-work-directory", 0755) != -1); atf_utils_create_file("the-work-directory/data-file", "%s", ""); kyua_run_params_t run_params; kyua_run_params_init(&run_params); run_params.work_directory = "./the-work-directory"; ATF_REQUIRE_MSG(fork_check(&run_params, check_work_directory, "data-file"), "Subprocess not in its own process group"); }
ATF_TC_BODY(fork_wait__unprivileged_group, tc) { const struct passwd* pw = getpwnam(atf_tc_get_config_var( tc, "unprivileged-user")); ATF_REQUIRE_MSG(pw != NULL, "Cannot find unprivileged user"); kyua_run_params_t run_params; kyua_run_params_init(&run_params); run_params.unprivileged_group = pw->pw_gid; ATF_REQUIRE_MSG(fork_check(&run_params, check_gid_not_root, NULL), "Subprocess is still running with GID set to root"); }
ATF_TC_BODY(fork_wait__env, tc) { kyua_env_set("HOME", "/non-existent/directory"); kyua_env_set("LANG", "C"); kyua_env_set("LC_ALL", "C"); kyua_env_set("LC_COLLATE", "C"); kyua_env_set("LC_CTYPE", "C"); kyua_env_set("LC_MESSAGES", "C"); kyua_env_set("LC_MONETARY", "C"); kyua_env_set("LC_NUMERIC", "C"); kyua_env_set("LC_TIME", "C"); kyua_env_set("LEAVE_ME_ALONE", "kill-some-day"); kyua_env_set("TZ", "EST+5"); ATF_REQUIRE_MSG(fork_check(NULL, check_env, NULL), "Unclean environment in subprocess"); }
int non_pipe_process(char ***cmd_mat) { int retval; if ((retval = execute_non_forking(*cmd_mat)) == 2) { long int sec1,uSec1; //set up time variables etimeStart(&sec1,&uSec1); //start time pid_t pid = fork_check(); if (pid == 0) { // child char **new_subcmd = process_redirection(*cmd_mat); execute_forking(new_subcmd); } else { // parent int status; if (strcmp(process_redirection(*cmd_mat)[0], "limits") == 0) { limits(pid); } else if (strcmp(process_redirection(*cmd_mat)[0], "etime") == 0) { etimeFinish(pid,sec1,uSec1); } else waitpid(pid, &status, 0); retval = 1; } } return retval; }
ATF_TC_BODY(fork_wait__umask, tc) { (void)umask(0222); ATF_REQUIRE_MSG(fork_check(NULL, check_umask, NULL), "Subprocess does not have the predetermined 0022 umask"); }
ATF_TC_BODY(fork_wait__session, tc) { ATF_REQUIRE_MSG(fork_check(NULL, check_session, NULL), "Subprocess not in its own process group"); }