static void test_emlink(void) { if (max_subdirs == 0) { tst_resm(TCONF, "EMLINK test is not appropriate"); return; } TEST(rename(TEST_EMLINK, TEST_NEW_EMLINK)); check_and_print(EMLINK); if (TEST_RETURN == 0) SAFE_RMDIR(cleanup, TEST_NEW_EMLINK); }
int main(int ac, char **av) { int lc; int rval; pid_t pid, pid1; int status; /* * parse standard options */ tst_parse_opts(ac, av, NULL, NULL); /* * perform global setup for test */ setup(); /* * check looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; if ((pid = FORK_OR_VFORK()) == -1) { tst_brkm(TBROK, cleanup, "fork() #1 failed"); } if (pid == 0) { /* first child */ /* set to nobody */ rval = setreuid(nobody_uid, nobody_uid); if (rval < 0) { tst_resm(TWARN, "setreuid failed to " "to set the real uid to %d and " "effective uid to %d", nobody_uid, nobody_uid); perror("setreuid"); exit(1); } /* create the a directory with 0700 permits */ if (mkdir(fdir, PERMS) == -1) { tst_resm(TWARN, "mkdir(%s, %#o) Failed", fdir, PERMS); exit(1); } /* create "old" file under it */ SAFE_TOUCH(cleanup, fname, 0700, NULL); exit(0); } /* wait for child to exit */ wait(&status); if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { tst_brkm(TBROK, cleanup, "First child failed to set " "up conditions for the test"); } if ((pid1 = FORK_OR_VFORK()) == -1) { tst_brkm(TBROK, cleanup, "fork() #2 failed"); } if (pid1 == 0) { /* second child */ /* set to bin */ if ((rval = seteuid(bin_uid)) == -1) { tst_resm(TWARN, "seteuid() failed"); perror("setreuid"); exit(1); } /* create "new" directory */ if (mkdir(mdir, PERMS) == -1) { tst_resm(TWARN, "mkdir(%s, %#o) failed", mdir, PERMS); exit(1); } SAFE_TOUCH(cleanup, mname, 0700, NULL); /* rename "old" to "new" */ TEST(rename(fname, mname)); if (TEST_RETURN != -1) { tst_resm(TFAIL, "call succeeded unexpectedly"); continue; } if (TEST_ERRNO != EACCES) { tst_resm(TFAIL, "Expected EACCES got %d", TEST_ERRNO); } else { tst_resm(TPASS, "rename() returned EACCES"); } /* set the process id back to root */ if (seteuid(0) == -1) { tst_resm(TWARN, "seteuid(0) failed"); exit(1); } /* clean up things in case we are looping */ SAFE_UNLINK(cleanup, fname); SAFE_UNLINK(cleanup, mname); SAFE_RMDIR(cleanup, fdir); SAFE_RMDIR(cleanup, mdir); } else { /* parent - let the second child carry on */ waitpid(pid1, &status, 0); if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { exit(WEXITSTATUS(status)); } else { exit(0); } } } /* * cleanup and exit */ cleanup(); tst_exit(); }