void test_init(int argc, char **argv) { pid_t pid; static FILE *pidf; char *val; struct sigaction sa = { .sa_handler = sig_hand, .sa_flags = SA_RESTART, }; sigemptyset(&sa.sa_mask); parseargs(argc, argv); val = getenv("ZDTM_NEWNS"); if (val) { unsetenv("ZDTM_NEWNS"); ns_create(argc, argv); exit(1); } val = getenv("ZDTM_EXE"); if (val) { test_log_init(outfile, "ns"); redir_stdfds(); unsetenv("ZDTM_EXE"); ns_init(argc, argv); exit(1); } val = getenv("ZDTM_GID"); if (val && (setgid(atoi(val)) == -1)) { fprintf(stderr, "Can't set gid: %m"); exit(1); } val = getenv("ZDTM_UID"); if (val && (setuid(atoi(val)) == -1)) { fprintf(stderr, "Can't set gid: %m"); exit(1); } if (sigaction(SIGTERM, &sa, NULL)) { fprintf(stderr, "Can't set SIGTERM handler: %m\n"); exit(1); } if (sigaction(SIGCHLD, &sa, NULL)) { fprintf(stderr, "Can't set SIGCHLD handler: %m\n"); exit(1); } setup_outfile(); redir_stdfds(); pidf = fopen(pidfile, "wx"); if (!pidf) { err("Can't create pid file %s: %m\n", pidfile); exit(1); } pid = fork(); if (pid < 0) { err("Daemonizing failed: %m\n"); exit(1); } if (pid) { /* parent will exit when the child is ready */ test_waitsig(); if (futex_get(&sig_received) == SIGCHLD) { int ret; waitpid(pid, &ret, 0); if (WIFEXITED(ret)) { err("Test exited with unexpectedly with code %d\n", WEXITSTATUS(ret)); exit(0); } if (WIFSIGNALED(ret)) { err("Test exited on unexpected signal %d\n", WTERMSIG(ret)); exit(0); } } fprintf(pidf, "%d\n", pid); fclose(pidf); _exit(0); } /* record the test pid to remember the ownership of the pidfile */ master_pid = getpid(); fclose(pidf); sa.sa_handler = SIG_DFL; if (sigaction(SIGCHLD, &sa, NULL)) { err("Can't reset SIGCHLD handler: %m\n"); exit(1); } if (setsid() < 0) { err("Can't become session group leader: %m\n"); exit(1); } srand48(time(NULL)); /* just in case we need it */ }
void test_init(int argc, char **argv) { pid_t pid; char *val; struct sigaction sa = { .sa_handler = sig_hand, .sa_flags = SA_RESTART, }; sigemptyset(&sa.sa_mask); parseargs(argc, argv); val = getenv("ZDTM_NEWNS"); if (val) { if (!strcmp(val, "1")) { ns_create(argc, argv); exit(1); } if (!strcmp(val, "2")) { test_log_init(outfile, "ns"); redir_stdfds(); ns_init(argc, argv); } } val = getenv("ZDTM_GROUPS"); if (val) { char *tok = NULL; unsigned int size = 0, groups[NGROUPS_MAX]; tok = strtok(val, " "); while (tok) { size++; groups[size - 1] = atoi(tok); tok = strtok(NULL, " "); } if (setgroups(size, groups)) { fprintf(stderr, "Can't set groups: %m"); exit(1); } } val = getenv("ZDTM_GID"); if (val && (setgid(atoi(val)) == -1)) { fprintf(stderr, "Can't set gid: %m"); exit(1); } val = getenv("ZDTM_UID"); if (val && (setuid(atoi(val)) == -1)) { fprintf(stderr, "Can't set gid: %m"); exit(1); } if (prctl(PR_SET_DUMPABLE, 1)) { fprintf(stderr, "Can't set the dumpable flag"); exit(1); } if (sigaction(SIGTERM, &sa, NULL)) { fprintf(stderr, "Can't set SIGTERM handler: %m\n"); exit(1); } if (sigaction(SIGCHLD, &sa, NULL)) { fprintf(stderr, "Can't set SIGCHLD handler: %m\n"); exit(1); } setup_outfile(); redir_stdfds(); pid = fork(); if (pid < 0) { pr_perror("Daemonizing failed"); exit(1); } if (pid) { /* parent will exit when the child is ready */ test_waitsig(); if (futex_get(&sig_received) == SIGCHLD) { int ret; if (waitpid(pid, &ret, 0) != pid) { pr_perror("Unable to wait %d, pid"); exit(1); } if (WIFEXITED(ret)) { pr_err("Test exited unexpectedly with code %d\n", WEXITSTATUS(ret)); exit(1); } if (WIFSIGNALED(ret)) { pr_err("Test exited on unexpected signal %d\n", WTERMSIG(ret)); exit(1); } } if (write_pidfile(pid)) exit(1); _exit(0); } if (setsid() < 0) { pr_perror("Can't become session group leader"); exit(1); } /* record the test pid to remember the ownership of the pidfile */ master_pid = getpid(); sa.sa_handler = SIG_DFL; if (sigaction(SIGCHLD, &sa, NULL)) { pr_perror("Can't reset SIGCHLD handler"); exit(1); } srand48(time(NULL)); /* just in case we need it */ }