static void test(void) { int status; /* unshares the mount ns */ if (unshare(CLONE_NEWNS) == -1) tst_brkm(TBROK | TERRNO, cleanup, "unshare failed"); /* makes sure parent mounts/umounts have no effect on a real system */ SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL); /* bind mounts DIRA to itself */ SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL); /* makes mount DIRA shared */ SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_SHARED, NULL); if (do_clone_tests(CLONE_NEWNS, child_func, NULL, NULL, NULL) == -1) tst_brkm(TBROK | TERRNO, cleanup, "clone failed"); /* waits for child to make a slave mount */ TST_CHECKPOINT_PARENT_WAIT(cleanup, &checkpoint1); /* bind mounts DIRB to DIRA making contents of DIRB visible * in DIRA */ SAFE_MOUNT(cleanup, DIRB, DIRA, "none", MS_BIND, NULL); TST_CHECKPOINT_SIGNAL_CHILD(cleanup, &checkpoint2); TST_CHECKPOINT_PARENT_WAIT(cleanup, &checkpoint1); SAFE_UMOUNT(cleanup, DIRA); TST_CHECKPOINT_SIGNAL_CHILD(cleanup, &checkpoint2); TST_CHECKPOINT_PARENT_WAIT(cleanup, &checkpoint1); /* checks that slave mount doesn't propagate to shared mount */ if ((access(DIRA"/A", F_OK) == 0) && (access(DIRA"/B", F_OK) == -1)) tst_resm(TPASS, "propagation from slave mount passed"); else tst_resm(TFAIL, "propagation form slave mount failed"); TST_CHECKPOINT_SIGNAL_CHILD(cleanup, &checkpoint2); SAFE_WAIT(cleanup, &status); if (WIFEXITED(status)) { if (WEXITSTATUS(status) == 0) tst_resm(TPASS, "propagation to slave mount passed"); else tst_resm(TFAIL, "propagation to slave mount failed"); } if (WIFSIGNALED(status)) { tst_resm(TBROK, "child was killed with signal %s", tst_strsig(WTERMSIG(status))); return; } SAFE_UMOUNT(cleanup, DIRA); }
int main(int ac, char **av) { int lc; char *msg; pid_t pid; if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); setup(av[0]); TEST_EXP_ENOS(exp_enos); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; if ((pid = FORK_OR_VFORK()) == -1) tst_brkm(TBROK|TERRNO, cleanup, "fork #1 failed"); if (pid == 0) { char *av[2]; av[0] = TEST_APP; av[1] = NULL; (void)execve(TEST_APP, av, NULL); perror("execve failed"); exit(1); } TST_CHECKPOINT_PARENT_WAIT(NULL, &checkpoint); TEST(creat(TEST_APP, O_WRONLY)); if (TEST_RETURN != -1) { tst_resm(TFAIL, "creat succeeded"); } else { if (TEST_ERRNO == ETXTBSY) tst_resm(TPASS, "creat received EXTBSY"); else tst_resm(TFAIL | TTERRNO, "creat failed with " "unexpected error"); } if (kill(pid, SIGKILL) == -1) tst_resm(TINFO | TERRNO, "kill failed"); if (wait(NULL) == -1) tst_brkm(TBROK|TERRNO, cleanup, "wait failed"); } cleanup(); tst_exit(); }
int main(int ac, char **av) { int child_pid; int status; int rval; int lc; const char *msg; if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); #ifdef UCLINUX maybe_run_child(&do_child, ""); #endif setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; /* Child is in new session we are not alowed to change pgid */ if ((child_pid = FORK_OR_VFORK()) == -1) tst_brkm(TBROK, cleanup, "fork() failed"); if (child_pid == 0) { #ifdef UCLINUX if (self_exec(av[0], "") < 0) tst_brkm(TBROK, cleanup, "self_exec failed"); #else do_child(); #endif } TST_CHECKPOINT_PARENT_WAIT(cleanup, &checkpoint); rval = setpgid(child_pid, getppid()); if (rval == -1 && errno == EPERM) { tst_resm(TPASS, "setpgid failed with EPERM"); } else { tst_resm(TFAIL, "retval %d, errno %d, expected errno %d", rval, errno, EPERM); } TST_CHECKPOINT_SIGNAL_CHILD(cleanup, &checkpoint); if (wait(&status) < 0) tst_resm(TFAIL | TERRNO, "wait() for child 1 failed"); if (!(WIFEXITED(status)) || (WEXITSTATUS(status) != 0)) tst_resm(TFAIL, "child 1 failed with status %d", WEXITSTATUS(status)); /* Child after exec() we are no longer allowed to set pgid */ if ((child_pid = FORK_OR_VFORK()) == -1) tst_resm(TFAIL, "Fork failed"); if (child_pid == 0) { if (execlp(TEST_APP, TEST_APP, NULL) < 0) perror("exec failed"); exit(127); } TST_CHECKPOINT_PARENT_WAIT(cleanup, &checkpoint); rval = setpgid(child_pid, getppid()); if (rval == -1 && errno == EACCES) { tst_resm(TPASS, "setpgid failed with EACCES"); } else { tst_resm(TFAIL, "retval %d, errno %d, expected errno %d", rval, errno, EACCES); } TST_CHECKPOINT_SIGNAL_CHILD(cleanup, &checkpoint); if (wait(&status) < 0) tst_resm(TFAIL | TERRNO, "wait() for child 2 failed"); if (!(WIFEXITED(status)) || (WEXITSTATUS(status) != 0)) tst_resm(TFAIL, "child 2 failed with status %d", WEXITSTATUS(status)); } cleanup(); tst_exit(); }