static void do_test(void) { int fd, ret, status; pid_t child; char buf[FS_BLOCKSIZE]; SAFE_TOUCH(cleanup, "testfilep", 0644, NULL); SAFE_TOUCH(cleanup, "testfilec", 0644, NULL); child = tst_fork(); switch (child) { case -1: tst_brkm(TBROK | TERRNO, cleanup, "fork failed"); case 0: do_child(); default: fd = SAFE_OPEN(cleanup, "testfilep", O_RDWR); memset(buf, 'a', FS_BLOCKSIZE); TST_SAFE_CHECKPOINT_WAIT(cleanup, 0); while (1) { ret = write(fd, buf, FS_BLOCKSIZE); if (ret < 0) { if (errno == ENOSPC) { break; } else { tst_brkm(TBROK | TERRNO, cleanup, "write failed unexpectedly"); } } } SAFE_CLOSE(cleanup, fd); TST_SAFE_CHECKPOINT_WAKE(cleanup, 0); } wait(&status); if (WIFEXITED(status) && WEXITSTATUS(status) == 1) { bug_reproduced = 1; } else { /* * If child process was killed by SIGBUS, bug is not reproduced. */ if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGBUS) { tst_brkm(TBROK | TERRNO, cleanup, "child process terminate unexpectedly"); } } SAFE_UNLINK(cleanup, "testfilep"); SAFE_UNLINK(cleanup, "testfilec"); }
int main(int ac, char **av) { int lc; tst_parse_opts(ac, av, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; TEST(open(fname, O_RDWR | O_CREAT, 0700)); fd = TEST_RETURN; if (TEST_RETURN == -1) { tst_resm(TFAIL | TTERRNO, "open(%s,O_RDWR|O_CREAT,0700) failed", fname); } else { tst_resm(TPASS, "open(%s, O_RDWR|O_CREAT,0700) returned %ld", fname, TEST_RETURN); SAFE_CLOSE(cleanup, fd); SAFE_UNLINK(cleanup, fname); } } cleanup(); tst_exit(); }
static void setup_ipc(void) { size_t size = getpagesize(); //TODO: Fallback to tst_tmpdir() if /dev/shm does not exits? snprintf(shm_path, sizeof(shm_path), "/dev/shm/ltp_%s_%d", tst_test->tid, getpid()); ipc_fd = open(shm_path, O_CREAT | O_EXCL | O_RDWR, 0600); if (ipc_fd < 0) tst_brk(TBROK | TERRNO, "open(%s)", shm_path); SAFE_FTRUNCATE(ipc_fd, size); results = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ipc_fd, 0); /* Checkpoints needs to be accessible from processes started by exec() */ if (tst_test->needs_checkpoints) sprintf(ipc_path, IPC_ENV_VAR "=%s", shm_path); else SAFE_UNLINK(shm_path); SAFE_CLOSE(ipc_fd); if (tst_test->needs_checkpoints) { tst_futexes = (char*)results + sizeof(struct results); tst_max_futexes = (size - sizeof(struct results))/sizeof(futex_t); } }
static void cleanup(void) { if (opt_shmid && shmid != -1) SAFE_SHMCTL(shmid, IPC_RMID, NULL); if (!opt_shmid && fd != -1) { SAFE_CLOSE(fd); SAFE_UNLINK(TEST_FILE); } if (mounted) tst_umount(MOUNT_DIR); if (restore_nr_hgpgs) { tst_res(TINFO, "restore nr_hugepages to %ld.", nr_hugepages); SAFE_FILE_PRINTF(path, "%ld", nr_hugepages); } if (restore_shmmax) SAFE_FILE_PRINTF(PATH_SHMMAX, "%llu", shmmax); if (restore_overcomm_hgpgs) { tst_res(TINFO, "restore nr_overcommit_hugepages to %ld.", nr_overcommit_hugepages); SAFE_FILE_PRINTF(pathover, "%ld", nr_overcommit_hugepages); } }
static void test_eloop(void) { TEST(rename(elooppathname, TEST_NEW_ELOOP)); check_and_print(ELOOP); if (TEST_RETURN == 0) SAFE_UNLINK(cleanup, TEST_NEW_ELOOP); }
int main(int argc, char *argv[]) { struct passwd *pwent; setup(); /* EISDIR */ if (acct("/") == -1 && errno == EISDIR) tst_resm(TPASS, "Failed with EISDIR as expected"); else tst_brkm(TFAIL | TERRNO, cleanup, "didn't fail as expected; expected EISDIR"); /* EACCES */ if (acct("/dev/null") == -1 && errno == EACCES) tst_resm(TPASS, "Failed with EACCES as expected"); else tst_brkm(TFAIL | TERRNO, cleanup, "didn't fail as expected; expected EACCES"); /* ENOENT */ if (acct("/tmp/does/not/exist") == -1 && errno == ENOENT) tst_resm(TPASS, "Failed with ENOENT as expected"); else tst_brkm(TBROK | TERRNO, cleanup, "didn't fail as expected; expected ENOENT"); /* ENOTDIR */ if (acct("/etc/fstab/") == -1 && errno == ENOTDIR) tst_resm(TPASS, "Failed with ENOTDIR as expected"); else tst_brkm(TFAIL | TERRNO, cleanup, "didn't fail as expected; expected ENOTDIR"); /* EPERM */ sprintf(tmpbuf, "./%s.%d", TCID, getpid()); fd = SAFE_CREAT(cleanup, tmpbuf, 0777); SAFE_CLOSE(cleanup, fd); if (acct(tmpbuf) == -1) tst_brkm(TBROK | TERRNO, cleanup, "acct failed unexpectedly"); pwent = SAFE_GETPWNAM(cleanup, "nobody"); SAFE_SETEUID(cleanup, pwent->pw_uid); if (acct(tmpbuf) == -1 && errno == EPERM) tst_resm(TPASS, "Failed with EPERM as expected"); else tst_brkm(TBROK | TERRNO, cleanup, "didn't fail as expected; expected EPERM"); SAFE_SETEUID(cleanup, 0); SAFE_UNLINK(cleanup, tmpbuf); cleanup(); tst_exit(); }
int mkfile(int size) { int fd, i; fd = SAFE_OPEN(TEST_FILENAME, O_RDWR | O_CREAT, 0600); SAFE_UNLINK(TEST_FILENAME); for (i = 0; i < size; i++) SAFE_WRITE(1, fd, "a", 1); SAFE_WRITE(1, fd, "\0", 1); if (fsync(fd) == -1) tst_brk(TBROK | TERRNO, "fsync()"); return fd; }
static void test_erofs(void) { if (mount(device, MNTPOINT, fs_type, MS_REMOUNT | MS_RDONLY, NULL) < 0) { tst_brkm(TBROK | TERRNO, cleanup, "mount device:%s failed", device); } TEST(rename(TEST_EROFS, TEST_NEW_EROFS)); check_and_print(EROFS); if (TEST_RETURN == 0) SAFE_UNLINK(cleanup, TEST_NEW_EROFS); if (mount(device, MNTPOINT, fs_type, MS_REMOUNT, NULL) < 0) { tst_brkm(TBROK | TERRNO, cleanup, "remount device:%s failed", device); } }
static void setup_ipc(void) { size_t size = getpagesize(); if (access("/dev/shm", F_OK) == 0) { snprintf(shm_path, sizeof(shm_path), "/dev/shm/ltp_%s_%d", tid, getpid()); } else { char *tmpdir; if (!tst_tmpdir_created()) tst_tmpdir(); tmpdir = tst_get_tmpdir(); snprintf(shm_path, sizeof(shm_path), "%s/ltp_%s_%d", tmpdir, tid, getpid()); free(tmpdir); } ipc_fd = open(shm_path, O_CREAT | O_EXCL | O_RDWR, 0600); if (ipc_fd < 0) tst_brk(TBROK | TERRNO, "open(%s)", shm_path); SAFE_CHMOD(shm_path, 0666); SAFE_FTRUNCATE(ipc_fd, size); results = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ipc_fd, 0); /* Checkpoints needs to be accessible from processes started by exec() */ if (tst_test->needs_checkpoints) { sprintf(ipc_path, IPC_ENV_VAR "=%s", shm_path); putenv(ipc_path); } else { SAFE_UNLINK(shm_path); } SAFE_CLOSE(ipc_fd); if (tst_test->needs_checkpoints) { tst_futexes = (char*)results + sizeof(struct results); tst_max_futexes = (size - sizeof(struct results))/sizeof(futex_t); } }
static void verify_inotify(void) { int inotify_fd, fd; pid_t pid; int i, tests; pid = SAFE_FORK(); if (pid == 0) { while (1) { for (i = 0; i < FILES; i++) { fd = SAFE_OPEN(names[i], O_CREAT | O_RDWR, 0600); SAFE_CLOSE(fd); } for (i = 0; i < FILES; i++) SAFE_UNLINK(names[i]); } } for (tests = 0; tests < TEARDOWNS; tests++) { inotify_fd = myinotify_init1(O_NONBLOCK); if (inotify_fd < 0) tst_brk(TBROK | TERRNO, "inotify_init failed"); for (i = 0; i < FILES; i++) { /* * Both failure and success are fine since * files are being deleted in parallel - this * is what provokes the race we want to test * for... */ myinotify_add_watch(inotify_fd, names[i], IN_MODIFY); } SAFE_CLOSE(inotify_fd); } /* We survived for given time - test succeeded */ tst_res(TPASS, "kernel survived inotify beating"); /* Kill the child creating / deleting files and wait for it */ SAFE_KILL(pid, SIGKILL); SAFE_WAIT(NULL); }
void dirtyc0w_test(void) { int i, fd, pid, fail = 0; char c; /* Create file */ fd = SAFE_OPEN(FNAME, O_WRONLY|O_CREAT|O_EXCL, 0444); SAFE_WRITE(1, fd, STR, sizeof(STR)-1); SAFE_CLOSE(fd); pid = SAFE_FORK(); if (!pid) { SAFE_SETGID(nobody_gid); SAFE_SETUID(nobody_uid); SAFE_EXECLP("dirtyc0w_child", "dirtyc0w_child", NULL); } TST_CHECKPOINT_WAIT(0); for (i = 0; i < 100; i++) { usleep(10000); SAFE_FILE_SCANF(FNAME, "%c", &c); if (c != 't') { fail = 1; break; } } SAFE_KILL(pid, SIGUSR1); tst_reap_children(); SAFE_UNLINK(FNAME); if (fail) tst_res(TFAIL, "Bug reproduced!"); else tst_res(TPASS, "Bug not reproduced"); }
static void verify_open(unsigned int n) { struct tcase *tc = &tcases[n]; struct stat buf; TEST(open(tc->filename, tc->flag, tc->mode)); fd = TST_RET; if (fd == -1) { tst_res(TFAIL, "Cannot open a file"); return; } SAFE_FSTAT(fd, &buf); if (!(buf.st_mode & tc->tst_bit)) tst_res(TFAIL, "%s is cleared unexpectedly", tc->desc); else tst_res(TPASS, "%s is set as expected", tc->desc); SAFE_CLOSE(fd); if (S_ISREG(buf.st_mode)) SAFE_UNLINK(tc->filename); }
void cleanup(void) { SAFE_CLOSE(NULL, fd); SAFE_UNLINK(NULL, __FILE__ "~"); tst_resm(TINFO, "got here"); }
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(); }
int main(int ac, char **av) { int lc; const char *msg; struct stat fbuf, lbuf; int cnt; char lname[255]; if ((msg = parse_opts(ac, av, options, &help)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); if (links_arg) { nlinks = atoi(links_arg); if (nlinks == 0) { tst_brkm(TBROK, NULL, "nlinks is not a positive number"); } } setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; for (cnt = 1; cnt < nlinks; cnt++) { sprintf(lname, "%s%d", fname, cnt); TEST(link(fname, lname)); if (TEST_RETURN == -1) { tst_resm(TFAIL, "link(%s, %s) Failed, errno=%d : %s", fname, lname, TEST_ERRNO, strerror(TEST_ERRNO)); } } SAFE_STAT(cleanup, fname, &fbuf); for (cnt = 1; cnt < nlinks; cnt++) { sprintf(lname, "%s%d", fname, cnt); SAFE_STAT(cleanup, lname, &lbuf); if (fbuf.st_nlink <= 1 || lbuf.st_nlink <= 1 || (fbuf.st_nlink != lbuf.st_nlink)) { tst_resm(TFAIL, "link(%s, %s[1-%d]) ret %ld for %d " "files, stat values do not match %d %d", fname, fname, nlinks, TEST_RETURN, nlinks, (int)fbuf.st_nlink, (int)lbuf.st_nlink); break; } } if (cnt >= nlinks) { tst_resm(TPASS, "link(%s, %s[1-%d]) ret %ld for %d files," "stat linkcounts match %d", fname, fname, nlinks, TEST_RETURN, nlinks, (int)fbuf.st_nlink); } for (cnt = 1; cnt < nlinks; cnt++) { sprintf(lname, "%s%d", fname, cnt); SAFE_UNLINK(cleanup, lname); } } cleanup(); tst_exit(); }
int main(int ac, char **av) { int lc; char *msg; int bytes_to_write, fd, num_bytes; pid_t pid; if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; fd = SAFE_OPEN(cleanup, file1, O_RDWR | O_CREAT, 0777); num_bytes = getpagesize(); do { if (num_bytes > strlen(buf)) bytes_to_write = strlen(buf); else bytes_to_write = num_bytes; num_bytes -= SAFE_WRITE(cleanup, 1, fd, buf, bytes_to_write); } while (0 < num_bytes); /* mmap the PAGESIZE bytes as read only. */ addr = SAFE_MMAP(cleanup, 0, sizeof(buf), PROT_READ, MAP_SHARED, fd, 0); if ((pid = FORK_OR_VFORK()) == -1) tst_brkm(TBROK | TERRNO, cleanup, "fork #1 failed"); if (pid == 0) { memcpy(addr, buf, strlen(buf)); exit(255); } if (waitpid(pid, &status, 0) == -1) tst_brkm(TBROK | TERRNO, cleanup, "waitpid failed"); if (!WIFEXITED(status)) tst_brkm(TBROK, cleanup, "child exited abnormally " "with status: %d", status); switch (status) { case 255: tst_brkm(TBROK, cleanup, "memcpy did not generate SIGSEGV"); case 0: tst_resm(TPASS, "got SIGSEGV as expected"); break; default: tst_brkm(TBROK, cleanup, "got unexpected signal: %d", status); break; } /* Change the protection to WRITE. */ TEST(mprotect(addr, sizeof(buf), PROT_WRITE)); if (TEST_RETURN != -1) { if (STD_FUNCTIONAL_TEST) { if ((pid = FORK_OR_VFORK()) == -1) tst_brkm(TBROK | TERRNO, cleanup, "fork #2 failed"); if (pid == 0) { memcpy(addr, buf, strlen(buf)); exit(0); } if (waitpid(pid, &status, 0) == -1) tst_brkm(TBROK | TERRNO, cleanup, "waitpid failed"); if (WIFEXITED(status) && WEXITSTATUS(status) == 0) tst_resm(TPASS, "didn't get SIGSEGV"); else tst_brkm(TBROK, cleanup, "child exited abnormally"); } else tst_resm(TPASS, "call succeeded"); } else { tst_resm(TFAIL | TERRNO, "mprotect failed"); continue; } SAFE_MUNMAP(cleanup, addr, sizeof(buf)); addr = MAP_FAILED; SAFE_CLOSE(cleanup, fd); SAFE_UNLINK(cleanup, file1); } cleanup(); tst_exit(); }
static void test_overcommit(void) { void *addr = NULL, *shmaddr = NULL; if (opt_shmid) { shmid = SAFE_SHMGET(key, (length / 2 * hugepagesize), SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W); } else { fd = SAFE_OPEN(TEST_FILE, O_CREAT | O_RDWR, 0755); addr = SAFE_MMAP(ADDR, (length / 2 * hugepagesize), PROTECTION, FLAGS, fd, 0); } if (opt_sysfs) { tst_res(TINFO, "check sysfs before allocation."); if (checksys(path_sys_sz_huge, "HugePages_Total", length / 2)) return; if (checksys(path_sys_sz_free, "HugePages_Free", length / 2)) return; if (checksys(path_sys_sz_surp, "HugePages_Surp", length / 2 - size)) return; if (checksys(path_sys_sz_resv, "HugePages_Rsvd", length / 2)) return; } else { tst_res(TINFO, "check /proc/meminfo before allocation."); if (checkproc(SAFE_READ_MEMINFO("HugePages_Total:"), "HugePages_Total", length / 2)) return; if (checkproc(SAFE_READ_MEMINFO("HugePages_Free:"), "HugePages_Free", length / 2)) return; if (checkproc(SAFE_READ_MEMINFO("HugePages_Surp:"), "HugePages_Surp", length / 2 - size)) return; if (checkproc(SAFE_READ_MEMINFO("HugePages_Rsvd:"), "HugePages_Rsvd", length / 2)) return; } if (opt_shmid) { tst_res(TINFO, "shmid: 0x%x", shmid); shmaddr = SAFE_SHMAT(shmid, ADDR, SHMAT_FLAGS); check_wr_bytes(shmaddr); } else { check_wr_bytes(addr); } if (opt_sysfs) { tst_res(TINFO, "check sysfs."); if (checksys(path_sys_sz_huge, "HugePages_Total", length / 2)) return; if (checksys(path_sys_sz_free, "HugePages_Free", 0)) return; if (checksys(path_sys_sz_surp, "HugePages_Surp", length / 2 - size)) return; if (checksys(path_sys_sz_resv, "HugePages_Rsvd", 0)) return; } else { tst_res(TINFO, "check /proc/meminfo."); if (checkproc(SAFE_READ_MEMINFO("HugePages_Total:"), "HugePages_Total", length / 2)) return; if (checkproc(SAFE_READ_MEMINFO("HugePages_Free:"), "HugePages_Free", 0)) return; if (checkproc(SAFE_READ_MEMINFO("HugePages_Surp:"), "HugePages_Surp", length / 2 - size)) return; if (checkproc(SAFE_READ_MEMINFO("HugePages_Rsvd:"), "HugePages_Rsvd", 0)) return; } if (opt_shmid) { SAFE_SHMDT(shmaddr); SAFE_SHMCTL(shmid, IPC_RMID, NULL); } else { SAFE_MUNMAP(addr, (length / 2 * hugepagesize)); SAFE_CLOSE(fd); SAFE_UNLINK(TEST_FILE); } tst_res(TPASS, "hugepages overcommit test pass"); }
int main(int ac, char **av) { int lc; char *addr; int fd, pid; char *buf = "abcdefghijklmnopqrstuvwxyz"; tst_parse_opts(ac, av, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; if ((fd = open(file1, O_RDWR | O_CREAT, 0777)) < 0) tst_brkm(TBROK, cleanup, "open failed"); SAFE_WRITE(cleanup, 1, fd, buf, strlen(buf)); /* * mmap the PAGESIZE bytes as read only. */ addr = mmap(0, strlen(buf), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) tst_brkm(TBROK, cleanup, "mmap failed"); /* * Try to change the protection to WRITE. */ TEST(mprotect(addr, strlen(buf), PROT_READ)); if (TEST_RETURN != -1) { if ((pid = FORK_OR_VFORK()) == -1) { tst_brkm(TBROK, cleanup, "fork failed"); } if (pid == 0) { memcpy(addr, buf, strlen(buf)); tst_resm(TINFO, "memcpy() did " "not generate SIGSEGV"); exit(1); } waitpid(pid, &status, 0); if (WEXITSTATUS(status) != 0) { tst_resm(TFAIL, "child returned " "unexpected status"); } else { tst_resm(TPASS, "SIGSEGV generated " "as expected"); } } else { tst_resm(TFAIL, "mprotect failed " "unexpectedly, errno: %d", errno); } /* clean up things in case we are looping */ SAFE_MUNMAP(cleanup, addr, strlen(buf)); SAFE_CLOSE(cleanup, fd); SAFE_UNLINK(cleanup, file1); } cleanup(); tst_exit(); }
static void clean(void) { SAFE_UNLINK(cleanup, testfilepath); SAFE_UNLINK(cleanup, testfile3); SAFE_UNLINK(cleanup, testfile); }
int main(int ac, char **av) { DIR *ddir, *opendir(); int fd; char *filname = "chdirtest"; char *filenames[3]; int lc; char *msg; if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); setup(); TEST_EXP_ENOS(exp_enos); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; SAFE_CHDIR(cleanup, testdir); fd = SAFE_CREAT(cleanup, filname, 0000); SAFE_CLOSE(cleanup, fd); if ((ddir = opendir(".")) == NULL) tst_brkm(TBROK | TERRNO, cleanup, "opendir(.) failed"); filenames[0] = "."; filenames[1] = ".."; filenames[2] = filname; checknames(filenames, sizeof(filenames) / sizeof(filenames[0]), ddir); closedir(ddir); TEST(chdir(filname)); if (TEST_RETURN != -1) tst_resm(TFAIL, "call succeeded unexpectedly"); else if (TEST_ERRNO != ENOTDIR) tst_resm(TFAIL | TTERRNO, "failed unexpectedly; wanted ENOTDIR"); else tst_resm(TPASS, "failed as expected with ENOTDIR"); if (unlink(filname) == -1) tst_brkm(TBROK | TERRNO, cleanup, "Couldn't remove file"); SAFE_CHDIR(cleanup, ".."); /* ELOOP */ SAFE_SYMLINK(cleanup, "test_eloop1", "test_eloop2"); SAFE_SYMLINK(cleanup, "test_eloop2", "test_eloop1"); TEST(chdir("test_eloop1")); if (TEST_RETURN != -1) { tst_resm(TFAIL, "call succeeded unexpectedly"); } else if (TEST_ERRNO != ELOOP) { tst_resm(TFAIL | TTERRNO, "failed unexpectedly; wanted ELOOP"); } else { tst_resm(TPASS, "failed as expected with ELOOP"); } SAFE_UNLINK(cleanup, "test_eloop1"); SAFE_UNLINK(cleanup, "test_eloop2"); } cleanup(); tst_exit(); }
int main(int ac, char **av) { int lc; const char *msg; struct stat buf; int i, links; char lname[255]; if ((msg = parse_opts(ac, av, options, &help)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); if (links_arg) { nlinks = atoi(links_arg); if (nlinks == 0) { tst_brkm(TBROK, NULL, "nlinks is not a positive number"); } if (nlinks > 1000) { tst_resm(TINFO, "nlinks > 1000 - may get errno:%d (EMLINK)", EMLINK); } } setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; if (nlinks) links = nlinks; else links = (lc % 90) + 10; /* Create links - 1 hardlinks so that the st_nlink == links */ for (i = 1; i < links; i++) { sprintf(lname, "%s%d", fname, i); TEST(link(fname, lname)); if (TEST_RETURN == -1) { tst_brkm(TFAIL | TTERRNO, cleanup, "link(%s, %s) Failed", fname, lname); } } SAFE_STAT(cleanup, fname, &buf); if (buf.st_nlink != (nlink_t)links) { tst_resm(TFAIL, "Wrong number of links for " "'%s' have %i, should be %i", fname, (int)buf.st_nlink, links); goto unlink; } for (i = 1; i < links; i++) { sprintf(lname, "%s%d", fname, i); SAFE_STAT(cleanup, lname, &buf); if (buf.st_nlink != (nlink_t)links) { tst_resm(TFAIL, "Wrong number of links for " "'%s' have %i, should be %i", lname, (int)buf.st_nlink, links); goto unlink; } } tst_resm(TPASS, "link() passed and linkcounts=%d match", links); unlink: for (i = 1; i < links; i++) { sprintf(lname, "%s%d", fname, i); SAFE_UNLINK(cleanup, lname); } } cleanup(); tst_exit(); }