2#include "fuse_config.h"
14#include <sys/socket.h>
20# define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
24static const char *basepath;
25static const char *basepath_r;
26static char testfile[1024];
27static char testfile2[1024];
28static char testdir[1024];
29static char testdir2[1024];
30static char testsock[1024];
31static char subfile[1280];
33static char testfile_r[1024];
34static char testfile2_r[1024];
35static char testdir_r[1024];
36static char testdir2_r[1024];
37static char subfile_r[1280];
39static char testname[256];
40static char testdata[] =
"abcdefghijklmnopqrstuvwxyz";
41static char testdata2[] =
"1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./";
42static const char *testdir_files[] = {
"f1",
"f2", NULL};
43static long seekdir_offsets[4];
44static char zerodata[4096];
45static int testdatalen =
sizeof(testdata) - 1;
46static int testdata2len =
sizeof(testdata2) - 1;
47static unsigned int testnum = 0;
48static unsigned int select_test = 0;
49static unsigned int skip_test = 0;
50static unsigned int unlinked_test = 0;
52#define MAX_ENTRIES 1024
60static void test_perror(
const char *func,
const char *msg)
62 fprintf(stderr,
"%s %s() - %s: %s\n", testname, func, msg,
66static void test_error(
const char *func,
const char *msg, ...)
67 __attribute__ ((format (printf, 2, 3)));
69static
void __start_test(const
char *fmt, ...)
70 __attribute__ ((format (printf, 1, 2)));
72static
void test_error(const
char *func, const
char *msg, ...)
75 fprintf(stderr,
"%s %s() - ", testname, func);
77 vfprintf(stderr, msg, ap);
79 fprintf(stderr,
"\n");
82static int is_dot_or_dotdot(
const char *name) {
83 return name[0] ==
'.' &&
84 (name[1] ==
'\0' || (name[1] ==
'.' && name[2] ==
'\0'));
87static void success(
void)
89 fprintf(stderr,
"%s OK\n", testname);
92#define this_test (&tests[testnum-1])
93#define next_test (&tests[testnum])
95static void __start_test(
const char *fmt, ...)
99 n = sprintf(testname,
"%3i [", testnum);
101 n += vsprintf(testname + n, fmt, ap);
103 sprintf(testname + n,
"]");
105 sprintf(testfile,
"%s/testfile.%d", basepath, testnum);
106 sprintf(testfile_r,
"%s/testfile.%d", basepath_r, testnum);
107 if (testnum > MAX_TESTS) {
108 fprintf(stderr,
"%s - too many tests\n", testname);
114#define start_test(msg, args...) { \
116 if ((select_test && testnum != select_test) || \
117 (testnum == skip_test)) { \
120 __start_test(msg, ##args); \
123#define PERROR(msg) test_perror(__FUNCTION__, msg)
124#define ERROR(msg, args...) test_error(__FUNCTION__, msg, ##args)
126#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
128static int st_check_size(
struct stat *st,
int len)
130 if (st->st_size != len) {
131 ERROR(
"length %u instead of %u", (
int) st->st_size,
138static int check_size(
const char *path,
int len)
141 int res = stat(path, &stbuf);
146 return st_check_size(&stbuf, len);
149static int check_testfile_size(
const char *path,
int len)
151 this_test->stat.st_size = len;
152 return check_size(path, len);
155static int st_check_type(
struct stat *st, mode_t type)
157 if ((st->st_mode & S_IFMT) != type) {
158 ERROR(
"type 0%o instead of 0%o", st->st_mode & S_IFMT, type);
164static int check_type(
const char *path, mode_t type)
167 int res = lstat(path, &stbuf);
172 return st_check_type(&stbuf, type);
175static int st_check_mode(
struct stat *st, mode_t mode)
177 if ((st->st_mode & ALLPERMS) != mode) {
178 ERROR(
"mode 0%o instead of 0%o", st->st_mode & ALLPERMS,
185static int check_mode(
const char *path, mode_t mode)
188 int res = lstat(path, &stbuf);
193 return st_check_mode(&stbuf, mode);
196static int check_testfile_mode(
const char *path, mode_t mode)
198 this_test->stat.st_mode &= ~ALLPERMS;
199 this_test->stat.st_mode |= mode;
200 return check_mode(path, mode);
203static int check_times(
const char *path, time_t atime, time_t mtime)
207 int res = lstat(path, &stbuf);
212 if (stbuf.st_atime != atime) {
213 ERROR(
"atime %li instead of %li", stbuf.st_atime, atime);
216 if (stbuf.st_mtime != mtime) {
217 ERROR(
"mtime %li instead of %li", stbuf.st_mtime, mtime);
227static int fcheck_times(
int fd, time_t atime, time_t mtime)
231 int res = fstat(fd, &stbuf);
236 if (stbuf.st_atime != atime) {
237 ERROR(
"atime %li instead of %li", stbuf.st_atime, atime);
240 if (stbuf.st_mtime != mtime) {
241 ERROR(
"mtime %li instead of %li", stbuf.st_mtime, mtime);
251static int st_check_nlink(
struct stat *st, nlink_t nlink)
253 if (st->st_nlink != nlink) {
254 ERROR(
"nlink %li instead of %li", (
long) st->st_nlink,
261static int check_nlink(
const char *path, nlink_t nlink)
264 int res = lstat(path, &stbuf);
269 return st_check_nlink(&stbuf, nlink);
272static int fcheck_stat(
int fd,
int flags,
struct stat *st)
275 int res = fstat(fd, &stbuf);
277 if (flags & O_PATH) {
280 if (errno == ESTALE || errno == EIO ||
281 errno == ENOENT || errno == EBADF)
289 err += st_check_type(&stbuf, st->st_mode & S_IFMT);
290 err += st_check_mode(&stbuf, st->st_mode & ALLPERMS);
291 err += st_check_size(&stbuf, st->st_size);
292 err += st_check_nlink(&stbuf, st->st_nlink);
297static int check_nonexist(
const char *path)
300 int res = lstat(path, &stbuf);
302 ERROR(
"file should not exist");
305 if (errno != ENOENT) {
306 ERROR(
"file should not exist: %s", strerror(errno));
312static int check_buffer(
const char *buf,
const char *data,
unsigned len)
314 if (memcmp(buf, data, len) != 0) {
315 ERROR(
"data mismatch");
321static int check_data(
const char *path,
const char *data,
int offset,
326 int fd = open(path, O_RDONLY);
331 if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
337 int rdlen = len <
sizeof(buf) ? len : sizeof(buf);
338 res = read(fd, buf, rdlen);
345 ERROR(
"short read: %u instead of %u", res, rdlen);
349 if (check_buffer(buf, data, rdlen) != 0) {
364static int fcheck_data(
int fd,
const char *data,
int offset,
369 if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
374 int rdlen = len <
sizeof(buf) ? len : sizeof(buf);
375 res = read(fd, buf, rdlen);
381 ERROR(
"short read: %u instead of %u", res, rdlen);
384 if (check_buffer(buf, data, rdlen) != 0) {
393static int check_dir_contents(
const char *path,
const char **contents)
398 int found[MAX_ENTRIES];
399 const char *cont[MAX_ENTRIES];
402 for (i = 0; contents[i]; i++) {
403 assert(i < MAX_ENTRIES - 3);
405 cont[i] = contents[i];
414 memset(found, 0,
sizeof(found));
427 if (is_dot_or_dotdot(de->d_name))
429 for (i = 0; cont[i] != NULL; i++) {
430 assert(i < MAX_ENTRIES);
431 if (strcmp(cont[i], de->d_name) == 0) {
433 ERROR(
"duplicate entry <%s>",
442 ERROR(
"unexpected entry <%s>", de->d_name);
446 for (i = 0; cont[i] != NULL; i++) {
448 ERROR(
"missing entry <%s>", cont[i]);
463static int create_file(
const char *path,
const char *data,
int len)
469 fd = creat(path, 0644);
475 res = write(fd, data, len);
482 ERROR(
"write is short: %u instead of %u", res, len);
492 res = check_type(path, S_IFREG);
495 res = check_mode(path, 0644);
498 res = check_nlink(path, 1);
501 res = check_size(path, len);
506 res = check_data(path, data, 0, len);
514static int create_path_fd(
const char *path,
const char *data,
int len)
519 res = create_file(path, data, len);
523 path_fd = open(path, O_PATH);
525 PERROR(
"open(O_PATH)");
531static int create_testfile(
const char *path,
const char *data,
int len)
533 struct test *t = this_test;
534 struct stat *st = &t->stat;
538 ERROR(
"testfile already created");
542 fd = create_path_fd(path, data, len);
557static int check_unlinked_testfile(
int fd)
559 struct stat *st = &this_test->stat;
562 return fcheck_stat(fd, O_PATH, st);
566static int check_unlinked_testfiles(
void)
576 while (testnum < num) {
578 start_test(
"check_unlinked_testfile");
582 err += check_unlinked_testfile(fd);
585 PERROR(
"close(test_fd)");
591 fprintf(stderr,
"%i unlinked testfile checks failed\n", -err);
598static int cleanup_dir(
const char *path,
const char **dir_files,
int quiet)
603 for (i = 0; dir_files[i]; i++) {
606 sprintf(fpath,
"%s/%s", path, dir_files[i]);
608 if (res == -1 && !quiet) {
619static int create_dir(
const char *path,
const char **dir_files)
625 res = mkdir(path, 0755);
630 res = check_type(path, S_IFDIR);
633 res = check_mode(path, 0755);
637 for (i = 0; dir_files[i]; i++) {
639 sprintf(fpath,
"%s/%s", path, dir_files[i]);
640 res = create_file(fpath,
"", 0);
642 cleanup_dir(path, dir_files, 1);
646 res = check_dir_contents(path, dir_files);
648 cleanup_dir(path, dir_files, 1);
655static int test_truncate(
int len)
657 const char *data = testdata;
658 int datalen = testdatalen;
661 start_test(
"truncate(%u)", (
int) len);
662 res = create_testfile(testfile, data, datalen);
666 res = truncate(testfile, len);
671 res = check_testfile_size(testfile, len);
676 if (len <= datalen) {
677 res = check_data(testfile, data, 0, len);
681 res = check_data(testfile, data, 0, datalen);
684 res = check_data(testfile, zerodata, datalen,
690 res = unlink(testfile);
695 res = check_nonexist(testfile);
703static int test_ftruncate(
int len,
int mode)
705 const char *data = testdata;
706 int datalen = testdatalen;
710 start_test(
"ftruncate(%u) mode: 0%03o", len, mode);
711 res = create_testfile(testfile, data, datalen);
715 fd = open(testfile, O_WRONLY);
721 res = fchmod(fd, mode);
727 res = check_testfile_mode(testfile, mode);
732 res = ftruncate(fd, len);
739 res = check_testfile_size(testfile, len);
744 if (len <= datalen) {
745 res = check_data(testfile, data, 0, len);
749 res = check_data(testfile, data, 0, datalen);
752 res = check_data(testfile, zerodata, datalen,
758 res = unlink(testfile);
763 res = check_nonexist(testfile);
771static int test_seekdir(
void)
776 struct dirent *de = NULL;
778 start_test(
"seekdir");
779 res = create_dir(testdir, testdir_files);
783 dp = opendir(testdir);
790 for (i = 0; i < ARRAY_SIZE(seekdir_offsets); i++) {
791 seekdir_offsets[i] = telldir(dp);
808 for (i--; i >= 0; i--) {
809 seekdir(dp, seekdir_offsets[i]);
812 ERROR(
"Unexpected end of directory after seekdir()");
818 res = cleanup_dir(testdir, testdir_files, 0);
824 cleanup_dir(testdir, testdir_files, 1);
828#ifdef HAVE_COPY_FILE_RANGE
829static int test_copy_file_range(
void)
831 const char *data = testdata;
832 int datalen = testdatalen;
836 off_t pos_in = 0, pos_out = 0;
838 start_test(
"copy_file_range");
840 fd_in = open(testfile, O_CREAT | O_RDWR, 0644);
845 res = write(fd_in, data, datalen);
851 if (res != datalen) {
852 ERROR(
"write is short: %u instead of %u", res, datalen);
858 fd_out = creat(testfile2, 0644);
864 res = copy_file_range(fd_in, &pos_in, fd_out, &pos_out, datalen, 0);
866 PERROR(
"copy_file_range");
871 if (res != datalen) {
872 ERROR(
"copy is short: %u instead of %u", res, datalen);
890 err = check_data(testfile2, data, 0, datalen);
892 res = unlink(testfile);
897 res = check_nonexist(testfile);
903 res = unlink(testfile2);
908 res = check_nonexist(testfile2);
918static int test_copy_file_range(
void)
924static int test_utime(
void)
927 time_t atime = 987631200;
928 time_t mtime = 123116400;
932 res = create_testfile(testfile, NULL, 0);
938 res = utime(testfile, &utm);
943 res = check_times(testfile, atime, mtime);
947 res = unlink(testfile);
952 res = check_nonexist(testfile);
960static int test_create(
void)
962 const char *data = testdata;
963 int datalen = testdatalen;
968 start_test(
"create");
970 fd = creat(testfile, 0644);
975 res = write(fd, data, datalen);
981 if (res != datalen) {
982 ERROR(
"write is short: %u instead of %u", res, datalen);
991 res = check_type(testfile, S_IFREG);
994 err += check_mode(testfile, 0644);
995 err += check_nlink(testfile, 1);
996 err += check_size(testfile, datalen);
997 err += check_data(testfile, data, 0, datalen);
998 res = unlink(testfile);
1003 res = check_nonexist(testfile);
1013static int test_create_unlink(
void)
1015 const char *data = testdata;
1016 int datalen = testdatalen;
1021 start_test(
"create+unlink");
1023 fd = open(testfile, O_CREAT | O_RDWR | O_TRUNC, 0644);
1028 res = unlink(testfile);
1034 res = check_nonexist(testfile);
1039 res = write(fd, data, datalen);
1045 if (res != datalen) {
1046 ERROR(
"write is short: %u instead of %u", res, datalen);
1051 .st_mode = S_IFREG | 0644,
1054 err = fcheck_stat(fd, O_RDWR, &st);
1055 err += fcheck_data(fd, data, 0, datalen);
1068static int test_mknod(
void)
1073 start_test(
"mknod");
1075 res = mknod(testfile, 0644, 0);
1080 res = check_type(testfile, S_IFREG);
1083 err += check_mode(testfile, 0644);
1084 err += check_nlink(testfile, 1);
1085 err += check_size(testfile, 0);
1086 res = unlink(testfile);
1091 res = check_nonexist(testfile);
1101#define test_open(exist, flags, mode) do_test_open(exist, flags, #flags, mode)
1103static int do_test_open(
int exist,
int flags,
const char *flags_str,
int mode)
1106 const char *data = testdata;
1107 int datalen = testdatalen;
1108 unsigned currlen = 0;
1114 start_test(
"open(%s, %s, 0%03o)", exist ?
"+" :
"-", flags_str, mode);
1117 res = create_file(testfile_r, testdata2, testdata2len);
1121 currlen = testdata2len;
1124 fd = open(testfile, flags, mode);
1125 if ((flags & O_CREAT) && (flags & O_EXCL) && exist) {
1127 ERROR(
"open should have failed");
1130 }
else if (errno == EEXIST)
1133 if (!(flags & O_CREAT) && !exist) {
1135 ERROR(
"open should have failed");
1138 }
else if (errno == ENOENT)
1146 if (flags & O_TRUNC)
1149 err += check_type(testfile, S_IFREG);
1151 err += check_mode(testfile, 0644);
1153 err += check_mode(testfile, mode);
1154 err += check_nlink(testfile, 1);
1155 err += check_size(testfile, currlen);
1156 if (exist && !(flags & O_TRUNC) && (mode & S_IRUSR))
1157 err += check_data(testfile, testdata2, 0, testdata2len);
1159 res = write(fd, data, datalen);
1160 if ((flags & O_ACCMODE) != O_RDONLY) {
1164 }
else if (res != datalen) {
1165 ERROR(
"write is short: %u instead of %u", res, datalen);
1168 if (datalen > (
int) currlen)
1171 err += check_size(testfile, currlen);
1173 if (mode & S_IRUSR) {
1174 err += check_data(testfile, data, 0, datalen);
1175 if (exist && !(flags & O_TRUNC) &&
1176 testdata2len > datalen)
1177 err += check_data(testfile,
1178 testdata2 + datalen,
1180 testdata2len - datalen);
1185 ERROR(
"write should have failed");
1187 }
else if (errno != EBADF) {
1192 off = lseek(fd, SEEK_SET, 0);
1193 if (off == (off_t) -1) {
1196 }
else if (off != 0) {
1197 ERROR(
"offset should have returned 0");
1200 res = read(fd, buf,
sizeof(buf));
1201 if ((flags & O_ACCMODE) != O_WRONLY) {
1207 currlen <
sizeof(buf) ? currlen : sizeof(buf);
1208 if (res != readsize) {
1209 ERROR(
"read is short: %i instead of %u",
1213 if ((flags & O_ACCMODE) != O_RDONLY) {
1214 err += check_buffer(buf, data, datalen);
1215 if (exist && !(flags & O_TRUNC) &&
1216 testdata2len > datalen)
1217 err += check_buffer(buf + datalen,
1218 testdata2 + datalen,
1219 testdata2len - datalen);
1221 err += check_buffer(buf, testdata2,
1227 ERROR(
"read should have failed");
1229 }
else if (errno != EBADF) {
1240 res = unlink(testfile);
1245 res = check_nonexist(testfile);
1248 res = check_nonexist(testfile_r);
1259#define test_open_acc(flags, mode, err) \
1260 do_test_open_acc(flags, #flags, mode, err)
1262static int do_test_open_acc(
int flags,
const char *flags_str,
int mode,
int err)
1264 const char *data = testdata;
1265 int datalen = testdatalen;
1269 start_test(
"open_acc(%s) mode: 0%03o message: '%s'", flags_str, mode,
1272 res = create_testfile(testfile, data, datalen);
1276 res = chmod(testfile, mode);
1282 res = check_testfile_mode(testfile, mode);
1286 fd = open(testfile, flags);
1294 ERROR(
"open should have failed");
1301 res = unlink(testfile);
1306 res = check_nonexist(testfile);
1309 res = check_nonexist(testfile_r);
1317static int test_symlink(
void)
1320 const char *data = testdata;
1321 int datalen = testdatalen;
1322 int linklen = strlen(testfile);
1326 start_test(
"symlink");
1327 res = create_testfile(testfile, data, datalen);
1332 res = symlink(testfile, testfile2);
1337 res = check_type(testfile2, S_IFLNK);
1340 err += check_mode(testfile2, 0777);
1341 err += check_nlink(testfile2, 1);
1342 res = readlink(testfile2, buf,
sizeof(buf));
1347 if (res != linklen) {
1348 ERROR(
"short readlink: %u instead of %u", res, linklen);
1351 if (memcmp(buf, testfile, linklen) != 0) {
1352 ERROR(
"link mismatch");
1355 err += check_size(testfile2, datalen);
1356 err += check_data(testfile2, data, 0, datalen);
1357 res = unlink(testfile2);
1362 res = check_nonexist(testfile2);
1368 res = unlink(testfile);
1373 res = check_nonexist(testfile);
1381static int test_link(
void)
1383 const char *data = testdata;
1384 int datalen = testdatalen;
1389 res = create_testfile(testfile, data, datalen);
1394 res = link(testfile, testfile2);
1399 res = check_type(testfile2, S_IFREG);
1402 err += check_mode(testfile2, 0644);
1403 err += check_nlink(testfile2, 2);
1404 err += check_size(testfile2, datalen);
1405 err += check_data(testfile2, data, 0, datalen);
1406 res = unlink(testfile);
1411 res = check_nonexist(testfile);
1415 err += check_nlink(testfile2, 1);
1416 res = unlink(testfile2);
1421 res = check_nonexist(testfile2);
1431static int test_link2(
void)
1433 const char *data = testdata;
1434 int datalen = testdatalen;
1438 start_test(
"link-unlink-link");
1439 res = create_testfile(testfile, data, datalen);
1444 res = link(testfile, testfile2);
1449 res = unlink(testfile);
1454 res = check_nonexist(testfile);
1457 res = link(testfile2, testfile);
1461 res = check_type(testfile, S_IFREG);
1464 err += check_mode(testfile, 0644);
1465 err += check_nlink(testfile, 2);
1466 err += check_size(testfile, datalen);
1467 err += check_data(testfile, data, 0, datalen);
1469 res = unlink(testfile2);
1474 err += check_nlink(testfile, 1);
1475 res = unlink(testfile);
1480 res = check_nonexist(testfile);
1490static int test_rename_file(
void)
1492 const char *data = testdata;
1493 int datalen = testdatalen;
1497 start_test(
"rename file");
1498 res = create_testfile(testfile, data, datalen);
1503 res = rename(testfile, testfile2);
1508 res = check_nonexist(testfile);
1511 res = check_type(testfile2, S_IFREG);
1514 err += check_mode(testfile2, 0644);
1515 err += check_nlink(testfile2, 1);
1516 err += check_size(testfile2, datalen);
1517 err += check_data(testfile2, data, 0, datalen);
1518 res = unlink(testfile2);
1523 res = check_nonexist(testfile2);
1533static int test_rename_dir(
void)
1538 start_test(
"rename dir");
1539 res = create_dir(testdir, testdir_files);
1544 res = rename(testdir, testdir2);
1547 cleanup_dir(testdir, testdir_files, 1);
1550 res = check_nonexist(testdir);
1552 cleanup_dir(testdir, testdir_files, 1);
1555 res = check_type(testdir2, S_IFDIR);
1557 cleanup_dir(testdir2, testdir_files, 1);
1560 err += check_mode(testdir2, 0755);
1561 err += check_dir_contents(testdir2, testdir_files);
1562 err += cleanup_dir(testdir2, testdir_files, 0);
1563 res = rmdir(testdir2);
1568 res = check_nonexist(testdir2);
1578static int test_rename_dir_loop(
void)
1580#define PATH(p) (snprintf(path, sizeof path, "%s/%s", testdir, p), path)
1581#define PATH2(p) (snprintf(path2, sizeof path2, "%s/%s", testdir, p), path2)
1583 char path[1280], path2[1280];
1587 start_test(
"rename dir loop");
1589 res = create_dir(testdir, testdir_files);
1593 res = mkdir(PATH(
"a"), 0755);
1599 res = rename(PATH(
"a"), PATH2(
"a"));
1606 res = rename(PATH(
"a"), PATH2(
"a/b"));
1607 if (res == 0 || errno != EINVAL) {
1612 res = mkdir(PATH(
"a/b"), 0755);
1618 res = mkdir(PATH(
"a/b/c"), 0755);
1625 res = rename(PATH(
"a"), PATH2(
"a/b/c"));
1626 if (res == 0 || errno != EINVAL) {
1632 res = rename(PATH(
"a"), PATH2(
"a/b/c/a"));
1633 if (res == 0 || errno != EINVAL) {
1639 res = rename(PATH(
"a/b/c"), PATH2(
"a"));
1640 if (res == 0 || errno != ENOTEMPTY) {
1645 res = open(PATH(
"a/foo"), O_CREAT, 0644);
1652 res = rename(PATH(
"a/foo"), PATH2(
"a/bar"));
1658 res = rename(PATH(
"a/bar"), PATH2(
"a/foo"));
1664 res = rename(PATH(
"a/foo"), PATH2(
"a/b/bar"));
1670 res = rename(PATH(
"a/b/bar"), PATH2(
"a/foo"));
1676 res = rename(PATH(
"a/foo"), PATH2(
"a/b/c/bar"));
1682 res = rename(PATH(
"a/b/c/bar"), PATH2(
"a/foo"));
1688 res = open(PATH(
"a/bar"), O_CREAT, 0644);
1695 res = rename(PATH(
"a/foo"), PATH2(
"a/bar"));
1701 unlink(PATH(
"a/bar"));
1703 res = rename(PATH(
"a/b"), PATH2(
"a/d"));
1709 res = rename(PATH(
"a/d"), PATH2(
"a/b"));
1715 res = mkdir(PATH(
"a/d"), 0755);
1721 res = rename(PATH(
"a/b"), PATH2(
"a/d"));
1727 res = rename(PATH(
"a/d"), PATH2(
"a/b"));
1733 res = mkdir(PATH(
"a/d"), 0755);
1739 res = mkdir(PATH(
"a/d/e"), 0755);
1746 res = rename(PATH(
"a/b"), PATH2(
"a/d"));
1747 if (res == 0 || (errno != ENOTEMPTY && errno != EEXIST)) {
1752 rmdir(PATH(
"a/d/e"));
1755 rmdir(PATH(
"a/b/c"));
1759 err += cleanup_dir(testdir, testdir_files, 0);
1760 res = rmdir(testdir);
1765 res = check_nonexist(testdir);
1775 unlink(PATH(
"a/bar"));
1777 rmdir(PATH(
"a/d/e"));
1780 rmdir(PATH(
"a/b/c"));
1784 cleanup_dir(testdir, testdir_files, 1);
1793static int test_mkfifo(
void)
1798 start_test(
"mkfifo");
1800 res = mkfifo(testfile, 0644);
1805 res = check_type(testfile, S_IFIFO);
1808 err += check_mode(testfile, 0644);
1809 err += check_nlink(testfile, 1);
1810 res = unlink(testfile);
1815 res = check_nonexist(testfile);
1825static int test_mkdir(
void)
1829 const char *dir_contents[] = {NULL};
1831 start_test(
"mkdir");
1833 res = mkdir(testdir, 0755);
1838 res = check_type(testdir, S_IFDIR);
1841 err += check_mode(testdir, 0755);
1845 err += check_dir_contents(testdir, dir_contents);
1846 res = rmdir(testdir);
1851 res = check_nonexist(testdir);
1861static int test_socket(
void)
1863 struct sockaddr_un su;
1867 const size_t test_sock_len = strlen(testsock) + 1;
1869 start_test(
"socket");
1870 if (test_sock_len >
sizeof(su.sun_path)) {
1871 fprintf(stderr,
"Need to shorten mount point by %zu chars\n",
1872 strlen(testsock) + 1 -
sizeof(su.sun_path));
1876 fd = socket(AF_UNIX, SOCK_STREAM, 0);
1881 su.sun_family = AF_UNIX;
1883 strncpy(su.sun_path, testsock, test_sock_len);
1884 su.sun_path[
sizeof(su.sun_path) - 1] =
'\0';
1885 res = bind(fd, (
struct sockaddr*)&su,
sizeof(su));
1891 res = check_type(testsock, S_IFSOCK);
1896 err += check_nlink(testsock, 1);
1898 res = unlink(testsock);
1903 res = check_nonexist(testsock);
1913#define test_create_ro_dir(flags) \
1914 do_test_create_ro_dir(flags, #flags)
1916static int do_test_create_ro_dir(
int flags,
const char *flags_str)
1922 start_test(
"open(%s) in read-only directory", flags_str);
1924 res = mkdir(testdir, 0555);
1929 fd = open(subfile, flags, 0644);
1933 ERROR(
"open should have failed");
1936 res = check_nonexist(subfile);
1941 res = rmdir(testdir);
1946 res = check_nonexist(testdir);
1960static int test_create_tmpfile(
void)
1963 int res = mkdir(testdir, 0777);
1967 start_test(
"create tmpfile");
1969 int fd = open(testdir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
1971 if (errno == ENOTSUP) {
1977 PERROR(
"open O_TMPFILE | O_RDWR");
1982 fd = open(testdir, O_TMPFILE | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
1984 PERROR(
"open with O_TMPFILE | O_WRONLY | O_EXCL");
1989 fd = open(testdir, O_TMPFILE | O_RDONLY, S_IRUSR);
1991 ERROR(
"open with O_TMPFILE | O_RDONLY succeeded");
1999static int test_create_and_link_tmpfile(
void)
2007 int res = mkdir(testdir, 0777);
2011 start_test(
"create and link tmpfile");
2013 int fd = open(testdir, O_TMPFILE | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
2015 if (errno == ENOTSUP) {
2020 PERROR(
"open with O_TMPFILE | O_RDWR | O_EXCL");
2024 if (!linkat(fd,
"", AT_FDCWD, testfile, AT_EMPTY_PATH)) {
2025 ERROR(
"linkat succeeded on a tmpfile opened with O_EXCL");
2030 fd = open(testdir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
2032 PERROR(
"open O_TMPFILE");
2036 if (check_nonexist(testfile)) {
2040 if (linkat(fd,
"", AT_FDCWD, testfile, AT_EMPTY_PATH)) {
2041 PERROR(
"linkat tempfile");
2046 if (check_nlink(testfile, 1)) {
2056int main(
int argc,
char *argv[])
2063 if (argc < 2 || argc > 4) {
2064 fprintf(stderr,
"usage: %s testdir [:realdir] [[-]test#] [-u]\n", argv[0]);
2068 basepath_r = basepath;
2069 for (a = 2; a < argc; a++) {
2071 char *arg = argv[a];
2072 if (arg[0] ==
':') {
2073 basepath_r = arg + 1;
2075 if (arg[0] ==
'-') {
2077 if (arg[0] ==
'u') {
2081 skip_test = strtoul(arg, &endptr, 10);
2084 select_test = strtoul(arg, &endptr, 10);
2086 if (arg[0] ==
'\0' || *endptr !=
'\0') {
2087 fprintf(stderr,
"invalid option: '%s'\n", argv[a]);
2092 assert(strlen(basepath) < 512);
2093 assert(strlen(basepath_r) < 512);
2094 if (basepath[0] !=
'/') {
2095 fprintf(stderr,
"testdir must be an absolute path\n");
2099 sprintf(testfile,
"%s/testfile", basepath);
2100 sprintf(testfile2,
"%s/testfile2", basepath);
2101 sprintf(testdir,
"%s/testdir", basepath);
2102 sprintf(testdir2,
"%s/testdir2", basepath);
2103 sprintf(subfile,
"%s/subfile", testdir2);
2104 sprintf(testsock,
"%s/testsock", basepath);
2106 sprintf(testfile_r,
"%s/testfile", basepath_r);
2107 sprintf(testfile2_r,
"%s/testfile2", basepath_r);
2108 sprintf(testdir_r,
"%s/testdir", basepath_r);
2109 sprintf(testdir2_r,
"%s/testdir2", basepath_r);
2110 sprintf(subfile_r,
"%s/subfile", testdir2_r);
2112 is_root = (geteuid() == 0);
2114 err += test_create();
2115 err += test_create_unlink();
2116 err += test_symlink();
2118 err += test_link2();
2119 err += test_mknod();
2120 err += test_mkfifo();
2121 err += test_mkdir();
2122 err += test_rename_file();
2123 err += test_rename_dir();
2124 err += test_rename_dir_loop();
2125 err += test_seekdir();
2126 err += test_socket();
2127 err += test_utime();
2128 err += test_truncate(0);
2129 err += test_truncate(testdatalen / 2);
2130 err += test_truncate(testdatalen);
2131 err += test_truncate(testdatalen + 100);
2132 err += test_ftruncate(0, 0600);
2133 err += test_ftruncate(testdatalen / 2, 0600);
2134 err += test_ftruncate(testdatalen, 0600);
2135 err += test_ftruncate(testdatalen + 100, 0600);
2136 err += test_ftruncate(0, 0400);
2137 err += test_ftruncate(0, 0200);
2138 err += test_ftruncate(0, 0000);
2139 err += test_open(0, O_RDONLY, 0);
2140 err += test_open(1, O_RDONLY, 0);
2141 err += test_open(1, O_RDWR, 0);
2142 err += test_open(1, O_WRONLY, 0);
2143 err += test_open(0, O_RDWR | O_CREAT, 0600);
2144 err += test_open(1, O_RDWR | O_CREAT, 0600);
2145 err += test_open(0, O_RDWR | O_CREAT | O_TRUNC, 0600);
2146 err += test_open(1, O_RDWR | O_CREAT | O_TRUNC, 0600);
2147 err += test_open(0, O_RDONLY | O_CREAT, 0600);
2148 err += test_open(0, O_RDONLY | O_CREAT, 0400);
2149 err += test_open(0, O_RDONLY | O_CREAT, 0200);
2150 err += test_open(0, O_RDONLY | O_CREAT, 0000);
2151 err += test_open(0, O_WRONLY | O_CREAT, 0600);
2152 err += test_open(0, O_WRONLY | O_CREAT, 0400);
2153 err += test_open(0, O_WRONLY | O_CREAT, 0200);
2154 err += test_open(0, O_WRONLY | O_CREAT, 0000);
2155 err += test_open(0, O_RDWR | O_CREAT, 0400);
2156 err += test_open(0, O_RDWR | O_CREAT, 0200);
2157 err += test_open(0, O_RDWR | O_CREAT, 0000);
2158 err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0600);
2159 err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0600);
2160 err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0000);
2161 err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0000);
2162 err += test_open_acc(O_RDONLY, 0600, 0);
2163 err += test_open_acc(O_WRONLY, 0600, 0);
2164 err += test_open_acc(O_RDWR, 0600, 0);
2165 err += test_open_acc(O_RDONLY, 0400, 0);
2166 err += test_open_acc(O_WRONLY, 0200, 0);
2168 err += test_open_acc(O_RDONLY | O_TRUNC, 0400, EACCES);
2169 err += test_open_acc(O_WRONLY, 0400, EACCES);
2170 err += test_open_acc(O_RDWR, 0400, EACCES);
2171 err += test_open_acc(O_RDONLY, 0200, EACCES);
2172 err += test_open_acc(O_RDWR, 0200, EACCES);
2173 err += test_open_acc(O_RDONLY, 0000, EACCES);
2174 err += test_open_acc(O_WRONLY, 0000, EACCES);
2175 err += test_open_acc(O_RDWR, 0000, EACCES);
2177 err += test_create_ro_dir(O_CREAT);
2178 err += test_create_ro_dir(O_CREAT | O_EXCL);
2179 err += test_create_ro_dir(O_CREAT | O_WRONLY);
2180 err += test_create_ro_dir(O_CREAT | O_TRUNC);
2181 err += test_copy_file_range();
2183 err += test_create_tmpfile();
2184 err += test_create_and_link_tmpfile();
2193 fprintf(stderr,
"%i tests failed\n", -err);
2197 return check_unlinked_testfiles();