2#include "fuse_config.h"
15#include <sys/socket.h>
21# define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
25static const char *basepath;
26static const char *basepath_r;
27static char testfile[1024];
28static char testfile2[1024];
29static char testdir[1024];
30static char testdir2[1024];
31static char testsock[1024];
32static char subfile[1280];
34static char testfile_r[1024];
35static char testfile2_r[1024];
36static char testdir_r[1024];
37static char testdir2_r[1024];
38static char subfile_r[1280];
40static char testname[256];
41static char testdata[] =
"abcdefghijklmnopqrstuvwxyz";
42static char testdata2[] =
"1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./";
43static const char *testdir_files[] = {
"f1",
"f2", NULL};
44static long seekdir_offsets[4];
45static char zerodata[4096];
46static int testdatalen =
sizeof(testdata) - 1;
47static int testdata2len =
sizeof(testdata2) - 1;
48static unsigned int testnum = 0;
49static unsigned int select_test = 0;
50static unsigned int skip_test = 0;
51static unsigned int unlinked_test = 0;
53#define MAX_ENTRIES 1024
61static void test_perror(
const char *func,
const char *msg)
63 fprintf(stderr,
"%s %s() - %s: %s\n", testname, func, msg,
67static void test_error(
const char *func,
const char *msg, ...)
68 __attribute__ ((format (printf, 2, 3)));
70static
void __start_test(const
char *fmt, ...)
71 __attribute__ ((format (printf, 1, 2)));
73static
void test_error(const
char *func, const
char *msg, ...)
76 fprintf(stderr,
"%s %s() - ", testname, func);
78 vfprintf(stderr, msg, ap);
80 fprintf(stderr,
"\n");
83static int is_dot_or_dotdot(
const char *name) {
84 return name[0] ==
'.' &&
85 (name[1] ==
'\0' || (name[1] ==
'.' && name[2] ==
'\0'));
92static double test_elapsed(
void)
94 static struct timespec start;
97 clock_gettime(CLOCK_MONOTONIC, &now);
98 if (start.tv_sec == 0 && start.tv_nsec == 0)
100 return (now.tv_sec - start.tv_sec) +
101 (now.tv_nsec - start.tv_nsec) / 1e9;
104static void success(
void)
106 fprintf(stderr,
"+%8.3fs %s OK\n", test_elapsed(), testname);
109#define this_test (&tests[testnum-1])
110#define next_test (&tests[testnum])
112static void __start_test(
const char *fmt, ...)
116 n = sprintf(testname,
"%3i [", testnum);
118 n += vsprintf(testname + n, fmt, ap);
120 sprintf(testname + n,
"]");
122 sprintf(testfile,
"%s/testfile.%d", basepath, testnum);
123 sprintf(testfile_r,
"%s/testfile.%d", basepath_r, testnum);
124 if (testnum > MAX_TESTS) {
125 fprintf(stderr,
"%s - too many tests\n", testname);
132 fprintf(stderr,
"+%8.3fs %s START\n", test_elapsed(), testname);
136#define start_test(msg, args...) { \
138 if ((select_test && testnum != select_test) || \
139 (testnum == skip_test)) { \
142 __start_test(msg, ##args); \
145#define PERROR(msg) test_perror(__FUNCTION__, msg)
146#define ERROR(msg, args...) test_error(__FUNCTION__, msg, ##args)
148#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
150static int st_check_size(
struct stat *st,
int len)
152 if (st->st_size != len) {
153 ERROR(
"length %u instead of %u", (
int) st->st_size,
160static int check_size(
const char *path,
int len)
163 int res = stat(path, &stbuf);
168 return st_check_size(&stbuf, len);
171static int check_testfile_size(
const char *path,
int len)
173 this_test->stat.st_size = len;
174 return check_size(path, len);
177static int st_check_type(
struct stat *st, mode_t type)
179 if ((st->st_mode & S_IFMT) != type) {
180 ERROR(
"type 0%o instead of 0%o", st->st_mode & S_IFMT, type);
186static int check_type(
const char *path, mode_t type)
189 int res = lstat(path, &stbuf);
194 return st_check_type(&stbuf, type);
197static int st_check_mode(
struct stat *st, mode_t mode)
199 if ((st->st_mode & ALLPERMS) != mode) {
200 ERROR(
"mode 0%o instead of 0%o", st->st_mode & ALLPERMS,
207static int check_mode(
const char *path, mode_t mode)
210 int res = lstat(path, &stbuf);
215 return st_check_mode(&stbuf, mode);
218static int check_testfile_mode(
const char *path, mode_t mode)
220 this_test->stat.st_mode &= ~ALLPERMS;
221 this_test->stat.st_mode |= mode;
222 return check_mode(path, mode);
225static int check_times(
const char *path, time_t atime, time_t mtime)
229 int res = lstat(path, &stbuf);
234 if (stbuf.st_atime != atime) {
235 ERROR(
"atime %li instead of %li", stbuf.st_atime, atime);
238 if (stbuf.st_mtime != mtime) {
239 ERROR(
"mtime %li instead of %li", stbuf.st_mtime, mtime);
249static int fcheck_times(
int fd, time_t atime, time_t mtime)
253 int res = fstat(fd, &stbuf);
258 if (stbuf.st_atime != atime) {
259 ERROR(
"atime %li instead of %li", stbuf.st_atime, atime);
262 if (stbuf.st_mtime != mtime) {
263 ERROR(
"mtime %li instead of %li", stbuf.st_mtime, mtime);
273static int st_check_nlink(
struct stat *st, nlink_t nlink)
275 if (st->st_nlink != nlink) {
276 ERROR(
"nlink %li instead of %li", (
long) st->st_nlink,
283static int check_nlink(
const char *path, nlink_t nlink)
286 int res = lstat(path, &stbuf);
291 return st_check_nlink(&stbuf, nlink);
294static int fcheck_stat(
int fd,
int flags,
struct stat *st)
297 int res = fstat(fd, &stbuf);
299 if (flags & O_PATH) {
302 if (errno == ESTALE || errno == EIO ||
303 errno == ENOENT || errno == EBADF)
311 err += st_check_type(&stbuf, st->st_mode & S_IFMT);
312 err += st_check_mode(&stbuf, st->st_mode & ALLPERMS);
313 err += st_check_size(&stbuf, st->st_size);
314 err += st_check_nlink(&stbuf, st->st_nlink);
319static int check_nonexist(
const char *path)
322 int res = lstat(path, &stbuf);
324 ERROR(
"file should not exist");
327 if (errno != ENOENT) {
328 ERROR(
"file should not exist: %s", strerror(errno));
334static int check_buffer(
const char *buf,
const char *data,
unsigned len)
336 if (memcmp(buf, data, len) != 0) {
337 ERROR(
"data mismatch");
343static int check_data(
const char *path,
const char *data,
int offset,
348 int fd = open(path, O_RDONLY);
353 if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
359 int rdlen = len <
sizeof(buf) ? len : sizeof(buf);
360 res = read(fd, buf, rdlen);
367 ERROR(
"short read: %u instead of %u", res, rdlen);
371 if (check_buffer(buf, data, rdlen) != 0) {
386static int fcheck_data(
int fd,
const char *data,
int offset,
391 if (lseek(fd, offset, SEEK_SET) == (off_t) -1) {
396 int rdlen = len <
sizeof(buf) ? len : sizeof(buf);
397 res = read(fd, buf, rdlen);
403 ERROR(
"short read: %u instead of %u", res, rdlen);
406 if (check_buffer(buf, data, rdlen) != 0) {
415static int check_dir_contents(
const char *path,
const char **contents)
420 int found[MAX_ENTRIES];
421 const char *cont[MAX_ENTRIES];
424 for (i = 0; contents[i]; i++) {
425 assert(i < MAX_ENTRIES - 3);
427 cont[i] = contents[i];
436 memset(found, 0,
sizeof(found));
449 if (is_dot_or_dotdot(de->d_name))
451 for (i = 0; cont[i] != NULL; i++) {
452 assert(i < MAX_ENTRIES);
453 if (strcmp(cont[i], de->d_name) == 0) {
455 ERROR(
"duplicate entry <%s>",
464 ERROR(
"unexpected entry <%s>", de->d_name);
468 for (i = 0; cont[i] != NULL; i++) {
470 ERROR(
"missing entry <%s>", cont[i]);
485static int create_file(
const char *path,
const char *data,
int len)
491 fd = creat(path, 0644);
497 res = write(fd, data, len);
504 ERROR(
"write is short: %u instead of %u", res, len);
514 res = check_type(path, S_IFREG);
517 res = check_mode(path, 0644);
520 res = check_nlink(path, 1);
523 res = check_size(path, len);
528 res = check_data(path, data, 0, len);
536static int create_path_fd(
const char *path,
const char *data,
int len)
541 res = create_file(path, data, len);
545 path_fd = open(path, O_PATH);
547 PERROR(
"open(O_PATH)");
553static int create_testfile(
const char *path,
const char *data,
int len)
555 struct test *t = this_test;
556 struct stat *st = &t->stat;
560 ERROR(
"testfile already created");
564 fd = create_path_fd(path, data, len);
579static int check_unlinked_testfile(
int fd)
581 struct stat *st = &this_test->stat;
584 return fcheck_stat(fd, O_PATH, st);
588static int check_unlinked_testfiles(
void)
598 while (testnum < num) {
600 start_test(
"check_unlinked_testfile");
604 err += check_unlinked_testfile(fd);
607 PERROR(
"close(test_fd)");
613 fprintf(stderr,
"%i unlinked testfile checks failed\n", -err);
620static int cleanup_dir(
const char *path,
const char **dir_files,
int quiet)
625 for (i = 0; dir_files[i]; i++) {
628 sprintf(fpath,
"%s/%s", path, dir_files[i]);
630 if (res == -1 && !quiet) {
641static int create_dir(
const char *path,
const char **dir_files)
647 res = mkdir(path, 0755);
652 res = check_type(path, S_IFDIR);
655 res = check_mode(path, 0755);
659 for (i = 0; dir_files[i]; i++) {
661 sprintf(fpath,
"%s/%s", path, dir_files[i]);
662 res = create_file(fpath,
"", 0);
664 cleanup_dir(path, dir_files, 1);
668 res = check_dir_contents(path, dir_files);
670 cleanup_dir(path, dir_files, 1);
677static int test_truncate(
int len)
679 const char *data = testdata;
680 int datalen = testdatalen;
683 start_test(
"truncate(%u)", (
int) len);
684 res = create_testfile(testfile, data, datalen);
688 res = truncate(testfile, len);
693 res = check_testfile_size(testfile, len);
698 if (len <= datalen) {
699 res = check_data(testfile, data, 0, len);
703 res = check_data(testfile, data, 0, datalen);
706 res = check_data(testfile, zerodata, datalen,
712 res = unlink(testfile);
717 res = check_nonexist(testfile);
725static int test_ftruncate(
int len,
int mode)
727 const char *data = testdata;
728 int datalen = testdatalen;
732 start_test(
"ftruncate(%u) mode: 0%03o", len, mode);
733 res = create_testfile(testfile, data, datalen);
737 fd = open(testfile, O_WRONLY);
743 res = fchmod(fd, mode);
749 res = check_testfile_mode(testfile, mode);
754 res = ftruncate(fd, len);
761 res = check_testfile_size(testfile, len);
766 if (len <= datalen) {
767 res = check_data(testfile, data, 0, len);
771 res = check_data(testfile, data, 0, datalen);
774 res = check_data(testfile, zerodata, datalen,
780 res = unlink(testfile);
785 res = check_nonexist(testfile);
793static int test_seekdir(
void)
798 struct dirent *de = NULL;
800 start_test(
"seekdir");
801 res = create_dir(testdir, testdir_files);
805 dp = opendir(testdir);
812 for (i = 0; i < ARRAY_SIZE(seekdir_offsets); i++) {
813 seekdir_offsets[i] = telldir(dp);
830 for (i--; i >= 0; i--) {
831 seekdir(dp, seekdir_offsets[i]);
834 ERROR(
"Unexpected end of directory after seekdir()");
840 res = cleanup_dir(testdir, testdir_files, 0);
846 cleanup_dir(testdir, testdir_files, 1);
850#ifdef HAVE_COPY_FILE_RANGE
851static int test_copy_file_range(
void)
853 const char *data = testdata;
854 int datalen = testdatalen;
858 off_t pos_in = 0, pos_out = 0;
860 start_test(
"copy_file_range");
862 fd_in = open(testfile, O_CREAT | O_RDWR, 0644);
867 res = write(fd_in, data, datalen);
873 if (res != datalen) {
874 ERROR(
"write is short: %u instead of %u", res, datalen);
880 fd_out = creat(testfile2, 0644);
886 res = copy_file_range(fd_in, &pos_in, fd_out, &pos_out, datalen, 0);
888 PERROR(
"copy_file_range");
893 if (res != datalen) {
894 ERROR(
"copy is short: %u instead of %u", res, datalen);
912 err = check_data(testfile2, data, 0, datalen);
914 res = unlink(testfile);
919 res = check_nonexist(testfile);
925 res = unlink(testfile2);
930 res = check_nonexist(testfile2);
940static int test_copy_file_range(
void)
947static int test_statx(
void)
951 size_t msg_size =
sizeof(msg);
955 memset(&sb, 0,
sizeof(sb));
960 res = create_testfile(testfile, msg, msg_size);
964 res = statx(-1, testfile, AT_EMPTY_PATH,
965 STATX_BASIC_STATS | STATX_BTIME, &sb);
969 if (sb.stx_size != msg_size)
972 clock_gettime(CLOCK_REALTIME, &tp);
974 if (sb.stx_btime.tv_sec > tp.tv_sec)
977 if (sb.stx_btime.tv_sec == tp.tv_sec &&
978 sb.stx_btime.tv_nsec >= tp.tv_nsec)
987static int test_statx(
void)
993static int test_utime(
void)
996 time_t atime = 987631200;
997 time_t mtime = 123116400;
1000 start_test(
"utime");
1001 res = create_testfile(testfile, NULL, 0);
1006 utm.modtime = mtime;
1007 res = utime(testfile, &utm);
1012 res = check_times(testfile, atime, mtime);
1016 res = unlink(testfile);
1021 res = check_nonexist(testfile);
1029static int test_create(
void)
1031 const char *data = testdata;
1032 int datalen = testdatalen;
1037 start_test(
"create");
1039 fd = creat(testfile, 0644);
1044 res = write(fd, data, datalen);
1050 if (res != datalen) {
1051 ERROR(
"write is short: %u instead of %u", res, datalen);
1060 res = check_type(testfile, S_IFREG);
1063 err += check_mode(testfile, 0644);
1064 err += check_nlink(testfile, 1);
1065 err += check_size(testfile, datalen);
1066 err += check_data(testfile, data, 0, datalen);
1067 res = unlink(testfile);
1072 res = check_nonexist(testfile);
1082static int test_create_unlink(
void)
1084 const char *data = testdata;
1085 int datalen = testdatalen;
1090 start_test(
"create+unlink");
1092 fd = open(testfile, O_CREAT | O_RDWR | O_TRUNC, 0644);
1097 res = unlink(testfile);
1103 res = check_nonexist(testfile);
1108 res = write(fd, data, datalen);
1114 if (res != datalen) {
1115 ERROR(
"write is short: %u instead of %u", res, datalen);
1120 .st_mode = S_IFREG | 0644,
1123 err = fcheck_stat(fd, O_RDWR, &st);
1124 err += fcheck_data(fd, data, 0, datalen);
1137static int test_mknod(
void)
1142 start_test(
"mknod");
1144 res = mknod(testfile, 0644, 0);
1149 res = check_type(testfile, S_IFREG);
1152 err += check_mode(testfile, 0644);
1153 err += check_nlink(testfile, 1);
1154 err += check_size(testfile, 0);
1155 res = unlink(testfile);
1160 res = check_nonexist(testfile);
1170#define test_open(exist, flags, mode) do_test_open(exist, flags, #flags, mode)
1172static int do_test_open(
int exist,
int flags,
const char *flags_str,
int mode)
1175 const char *data = testdata;
1176 int datalen = testdatalen;
1177 unsigned currlen = 0;
1183 start_test(
"open(%s, %s, 0%03o)", exist ?
"+" :
"-", flags_str, mode);
1186 res = create_file(testfile_r, testdata2, testdata2len);
1190 currlen = testdata2len;
1193 fd = open(testfile, flags, mode);
1194 if ((flags & O_CREAT) && (flags & O_EXCL) && exist) {
1196 ERROR(
"open should have failed");
1199 }
else if (errno == EEXIST)
1202 if (!(flags & O_CREAT) && !exist) {
1204 ERROR(
"open should have failed");
1207 }
else if (errno == ENOENT)
1215 if (flags & O_TRUNC)
1218 err += check_type(testfile, S_IFREG);
1220 err += check_mode(testfile, 0644);
1222 err += check_mode(testfile, mode);
1223 err += check_nlink(testfile, 1);
1224 err += check_size(testfile, currlen);
1225 if (exist && !(flags & O_TRUNC) && (mode & S_IRUSR))
1226 err += check_data(testfile, testdata2, 0, testdata2len);
1228 res = write(fd, data, datalen);
1229 if ((flags & O_ACCMODE) != O_RDONLY) {
1233 }
else if (res != datalen) {
1234 ERROR(
"write is short: %u instead of %u", res, datalen);
1237 if (datalen > (
int) currlen)
1240 err += check_size(testfile, currlen);
1242 if (mode & S_IRUSR) {
1243 err += check_data(testfile, data, 0, datalen);
1244 if (exist && !(flags & O_TRUNC) &&
1245 testdata2len > datalen)
1246 err += check_data(testfile,
1247 testdata2 + datalen,
1249 testdata2len - datalen);
1254 ERROR(
"write should have failed");
1256 }
else if (errno != EBADF) {
1261 off = lseek(fd, SEEK_SET, 0);
1262 if (off == (off_t) -1) {
1265 }
else if (off != 0) {
1266 ERROR(
"offset should have returned 0");
1269 res = read(fd, buf,
sizeof(buf));
1270 if ((flags & O_ACCMODE) != O_WRONLY) {
1276 currlen <
sizeof(buf) ? currlen : sizeof(buf);
1277 if (res != readsize) {
1278 ERROR(
"read is short: %i instead of %u",
1282 if ((flags & O_ACCMODE) != O_RDONLY) {
1283 err += check_buffer(buf, data, datalen);
1284 if (exist && !(flags & O_TRUNC) &&
1285 testdata2len > datalen)
1286 err += check_buffer(buf + datalen,
1287 testdata2 + datalen,
1288 testdata2len - datalen);
1290 err += check_buffer(buf, testdata2,
1296 ERROR(
"read should have failed");
1298 }
else if (errno != EBADF) {
1309 res = unlink(testfile);
1314 res = check_nonexist(testfile);
1317 res = check_nonexist(testfile_r);
1328#define test_open_acc(flags, mode, err) \
1329 do_test_open_acc(flags, #flags, mode, err)
1331static int do_test_open_acc(
int flags,
const char *flags_str,
int mode,
int err)
1333 const char *data = testdata;
1334 int datalen = testdatalen;
1338 start_test(
"open_acc(%s) mode: 0%03o message: '%s'", flags_str, mode,
1341 res = create_testfile(testfile, data, datalen);
1345 res = chmod(testfile, mode);
1351 res = check_testfile_mode(testfile, mode);
1355 fd = open(testfile, flags);
1363 ERROR(
"open should have failed");
1370 res = unlink(testfile);
1375 res = check_nonexist(testfile);
1378 res = check_nonexist(testfile_r);
1386static int test_symlink(
void)
1389 const char *data = testdata;
1390 int datalen = testdatalen;
1391 int linklen = strlen(testfile);
1395 start_test(
"symlink");
1396 res = create_testfile(testfile, data, datalen);
1401 res = symlink(testfile, testfile2);
1406 res = check_type(testfile2, S_IFLNK);
1409 err += check_mode(testfile2, 0777);
1410 err += check_nlink(testfile2, 1);
1411 res = readlink(testfile2, buf,
sizeof(buf));
1416 if (res != linklen) {
1417 ERROR(
"short readlink: %u instead of %u", res, linklen);
1420 if (memcmp(buf, testfile, linklen) != 0) {
1421 ERROR(
"link mismatch");
1424 err += check_size(testfile2, datalen);
1425 err += check_data(testfile2, data, 0, datalen);
1426 res = unlink(testfile2);
1431 res = check_nonexist(testfile2);
1437 res = unlink(testfile);
1442 res = check_nonexist(testfile);
1450static int test_link(
void)
1452 const char *data = testdata;
1453 int datalen = testdatalen;
1458 res = create_testfile(testfile, data, datalen);
1463 res = link(testfile, testfile2);
1468 res = check_type(testfile2, S_IFREG);
1471 err += check_mode(testfile2, 0644);
1472 err += check_nlink(testfile2, 2);
1473 err += check_size(testfile2, datalen);
1474 err += check_data(testfile2, data, 0, datalen);
1475 res = unlink(testfile);
1480 res = check_nonexist(testfile);
1484 err += check_nlink(testfile2, 1);
1485 res = unlink(testfile2);
1490 res = check_nonexist(testfile2);
1500static int test_link2(
void)
1502 const char *data = testdata;
1503 int datalen = testdatalen;
1507 start_test(
"link-unlink-link");
1508 res = create_testfile(testfile, data, datalen);
1513 res = link(testfile, testfile2);
1518 res = unlink(testfile);
1523 res = check_nonexist(testfile);
1526 res = link(testfile2, testfile);
1530 res = check_type(testfile, S_IFREG);
1533 err += check_mode(testfile, 0644);
1534 err += check_nlink(testfile, 2);
1535 err += check_size(testfile, datalen);
1536 err += check_data(testfile, data, 0, datalen);
1538 res = unlink(testfile2);
1543 err += check_nlink(testfile, 1);
1544 res = unlink(testfile);
1549 res = check_nonexist(testfile);
1559static int test_rename_file(
void)
1561 const char *data = testdata;
1562 int datalen = testdatalen;
1566 start_test(
"rename file");
1567 res = create_testfile(testfile, data, datalen);
1572 res = rename(testfile, testfile2);
1577 res = check_nonexist(testfile);
1580 res = check_type(testfile2, S_IFREG);
1583 err += check_mode(testfile2, 0644);
1584 err += check_nlink(testfile2, 1);
1585 err += check_size(testfile2, datalen);
1586 err += check_data(testfile2, data, 0, datalen);
1587 res = unlink(testfile2);
1592 res = check_nonexist(testfile2);
1602static int test_rename_dir(
void)
1607 start_test(
"rename dir");
1608 res = create_dir(testdir, testdir_files);
1613 res = rename(testdir, testdir2);
1616 cleanup_dir(testdir, testdir_files, 1);
1619 res = check_nonexist(testdir);
1621 cleanup_dir(testdir, testdir_files, 1);
1624 res = check_type(testdir2, S_IFDIR);
1626 cleanup_dir(testdir2, testdir_files, 1);
1629 err += check_mode(testdir2, 0755);
1630 err += check_dir_contents(testdir2, testdir_files);
1631 err += cleanup_dir(testdir2, testdir_files, 0);
1632 res = rmdir(testdir2);
1637 res = check_nonexist(testdir2);
1647static int test_rename_dir_loop(
void)
1649#define PATH(p) (snprintf(path, sizeof path, "%s/%s", testdir, p), path)
1650#define PATH2(p) (snprintf(path2, sizeof path2, "%s/%s", testdir, p), path2)
1652 char path[1280], path2[1280];
1656 start_test(
"rename dir loop");
1658 res = create_dir(testdir, testdir_files);
1662 res = mkdir(PATH(
"a"), 0755);
1668 res = rename(PATH(
"a"), PATH2(
"a"));
1675 res = rename(PATH(
"a"), PATH2(
"a/b"));
1676 if (res == 0 || errno != EINVAL) {
1681 res = mkdir(PATH(
"a/b"), 0755);
1687 res = mkdir(PATH(
"a/b/c"), 0755);
1694 res = rename(PATH(
"a"), PATH2(
"a/b/c"));
1695 if (res == 0 || errno != EINVAL) {
1701 res = rename(PATH(
"a"), PATH2(
"a/b/c/a"));
1702 if (res == 0 || errno != EINVAL) {
1708 res = rename(PATH(
"a/b/c"), PATH2(
"a"));
1709 if (res == 0 || errno != ENOTEMPTY) {
1714 res = open(PATH(
"a/foo"), O_CREAT, 0644);
1721 res = rename(PATH(
"a/foo"), PATH2(
"a/bar"));
1727 res = rename(PATH(
"a/bar"), PATH2(
"a/foo"));
1733 res = rename(PATH(
"a/foo"), PATH2(
"a/b/bar"));
1739 res = rename(PATH(
"a/b/bar"), PATH2(
"a/foo"));
1745 res = rename(PATH(
"a/foo"), PATH2(
"a/b/c/bar"));
1751 res = rename(PATH(
"a/b/c/bar"), PATH2(
"a/foo"));
1757 res = open(PATH(
"a/bar"), O_CREAT, 0644);
1764 res = rename(PATH(
"a/foo"), PATH2(
"a/bar"));
1770 unlink(PATH(
"a/bar"));
1772 res = rename(PATH(
"a/b"), PATH2(
"a/d"));
1778 res = rename(PATH(
"a/d"), PATH2(
"a/b"));
1784 res = mkdir(PATH(
"a/d"), 0755);
1790 res = rename(PATH(
"a/b"), PATH2(
"a/d"));
1796 res = rename(PATH(
"a/d"), PATH2(
"a/b"));
1802 res = mkdir(PATH(
"a/d"), 0755);
1808 res = mkdir(PATH(
"a/d/e"), 0755);
1815 res = rename(PATH(
"a/b"), PATH2(
"a/d"));
1816 if (res == 0 || (errno != ENOTEMPTY && errno != EEXIST)) {
1821 rmdir(PATH(
"a/d/e"));
1824 rmdir(PATH(
"a/b/c"));
1828 err += cleanup_dir(testdir, testdir_files, 0);
1829 res = rmdir(testdir);
1834 res = check_nonexist(testdir);
1844 unlink(PATH(
"a/bar"));
1846 rmdir(PATH(
"a/d/e"));
1849 rmdir(PATH(
"a/b/c"));
1853 cleanup_dir(testdir, testdir_files, 1);
1862static int test_mkfifo(
void)
1867 start_test(
"mkfifo");
1869 res = mkfifo(testfile, 0644);
1874 res = check_type(testfile, S_IFIFO);
1877 err += check_mode(testfile, 0644);
1878 err += check_nlink(testfile, 1);
1879 res = unlink(testfile);
1884 res = check_nonexist(testfile);
1894static int test_mkdir(
void)
1898 const char *dir_contents[] = {NULL};
1900 start_test(
"mkdir");
1902 res = mkdir(testdir, 0755);
1907 res = check_type(testdir, S_IFDIR);
1910 err += check_mode(testdir, 0755);
1914 err += check_dir_contents(testdir, dir_contents);
1915 res = rmdir(testdir);
1920 res = check_nonexist(testdir);
1930static int test_socket(
void)
1932 struct sockaddr_un su;
1936 const size_t test_sock_len = strlen(testsock) + 1;
1938 start_test(
"socket");
1939 if (test_sock_len >
sizeof(su.sun_path)) {
1940 fprintf(stderr,
"Need to shorten mount point by %zu chars\n",
1941 strlen(testsock) + 1 -
sizeof(su.sun_path));
1945 fd = socket(AF_UNIX, SOCK_STREAM, 0);
1950 su.sun_family = AF_UNIX;
1952 strncpy(su.sun_path, testsock, test_sock_len);
1953 su.sun_path[
sizeof(su.sun_path) - 1] =
'\0';
1954 res = bind(fd, (
struct sockaddr*)&su,
sizeof(su));
1960 res = check_type(testsock, S_IFSOCK);
1965 err += check_nlink(testsock, 1);
1967 res = unlink(testsock);
1972 res = check_nonexist(testsock);
1982#define test_create_ro_dir(flags) \
1983 do_test_create_ro_dir(flags, #flags)
1985static int do_test_create_ro_dir(
int flags,
const char *flags_str)
1991 start_test(
"open(%s) in read-only directory", flags_str);
1993 res = mkdir(testdir, 0555);
1998 fd = open(subfile, flags, 0644);
2002 ERROR(
"open should have failed");
2005 res = check_nonexist(subfile);
2010 res = rmdir(testdir);
2015 res = check_nonexist(testdir);
2029static int test_create_tmpfile(
void)
2032 int res = mkdir(testdir, 0777);
2036 start_test(
"create tmpfile");
2038 int fd = open(testdir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
2040 if (errno == ENOTSUP) {
2046 PERROR(
"open O_TMPFILE | O_RDWR");
2051 fd = open(testdir, O_TMPFILE | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
2053 PERROR(
"open with O_TMPFILE | O_WRONLY | O_EXCL");
2058 fd = open(testdir, O_TMPFILE | O_RDONLY, S_IRUSR);
2060 ERROR(
"open with O_TMPFILE | O_RDONLY succeeded");
2068static int test_create_and_link_tmpfile(
void)
2076 int res = mkdir(testdir, 0777);
2080 start_test(
"create and link tmpfile");
2082 int fd = open(testdir, O_TMPFILE | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
2084 if (errno == ENOTSUP) {
2089 PERROR(
"open with O_TMPFILE | O_RDWR | O_EXCL");
2093 if (!linkat(fd,
"", AT_FDCWD, testfile, AT_EMPTY_PATH)) {
2094 ERROR(
"linkat succeeded on a tmpfile opened with O_EXCL");
2099 fd = open(testdir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
2101 PERROR(
"open O_TMPFILE");
2105 if (check_nonexist(testfile)) {
2109 if (linkat(fd,
"", AT_FDCWD, testfile, AT_EMPTY_PATH)) {
2110 PERROR(
"linkat tempfile");
2115 if (check_nlink(testfile, 1)) {
2125int main(
int argc,
char *argv[])
2134 setvbuf(stdout, NULL, _IOLBF, 0);
2137 if (argc < 2 || argc > 4) {
2138 fprintf(stderr,
"usage: %s testdir [:realdir] [[-]test#] [-u]\n", argv[0]);
2142 basepath_r = basepath;
2143 for (a = 2; a < argc; a++) {
2145 char *arg = argv[a];
2146 if (arg[0] ==
':') {
2147 basepath_r = arg + 1;
2149 if (arg[0] ==
'-') {
2151 if (arg[0] ==
'u') {
2155 skip_test = strtoul(arg, &endptr, 10);
2158 select_test = strtoul(arg, &endptr, 10);
2160 if (arg[0] ==
'\0' || *endptr !=
'\0') {
2161 fprintf(stderr,
"invalid option: '%s'\n", argv[a]);
2166 assert(strlen(basepath) < 512);
2167 assert(strlen(basepath_r) < 512);
2168 if (basepath[0] !=
'/') {
2169 fprintf(stderr,
"testdir must be an absolute path\n");
2173 sprintf(testfile,
"%s/testfile", basepath);
2174 sprintf(testfile2,
"%s/testfile2", basepath);
2175 sprintf(testdir,
"%s/testdir", basepath);
2176 sprintf(testdir2,
"%s/testdir2", basepath);
2177 sprintf(subfile,
"%s/subfile", testdir2);
2178 sprintf(testsock,
"%s/testsock", basepath);
2180 sprintf(testfile_r,
"%s/testfile", basepath_r);
2181 sprintf(testfile2_r,
"%s/testfile2", basepath_r);
2182 sprintf(testdir_r,
"%s/testdir", basepath_r);
2183 sprintf(testdir2_r,
"%s/testdir2", basepath_r);
2184 sprintf(subfile_r,
"%s/subfile", testdir2_r);
2186 is_root = (geteuid() == 0);
2188 err += test_create();
2189 err += test_create_unlink();
2190 err += test_symlink();
2192 err += test_link2();
2193 err += test_mknod();
2194 err += test_mkfifo();
2195 err += test_mkdir();
2196 err += test_rename_file();
2197 err += test_rename_dir();
2198 err += test_rename_dir_loop();
2199 err += test_seekdir();
2200 err += test_socket();
2201 err += test_utime();
2202 err += test_truncate(0);
2203 err += test_truncate(testdatalen / 2);
2204 err += test_truncate(testdatalen);
2205 err += test_truncate(testdatalen + 100);
2206 err += test_ftruncate(0, 0600);
2207 err += test_ftruncate(testdatalen / 2, 0600);
2208 err += test_ftruncate(testdatalen, 0600);
2209 err += test_ftruncate(testdatalen + 100, 0600);
2210 err += test_ftruncate(0, 0400);
2211 err += test_ftruncate(0, 0200);
2212 err += test_ftruncate(0, 0000);
2213 err += test_open(0, O_RDONLY, 0);
2214 err += test_open(1, O_RDONLY, 0);
2215 err += test_open(1, O_RDWR, 0);
2216 err += test_open(1, O_WRONLY, 0);
2217 err += test_open(0, O_RDWR | O_CREAT, 0600);
2218 err += test_open(1, O_RDWR | O_CREAT, 0600);
2219 err += test_open(0, O_RDWR | O_CREAT | O_TRUNC, 0600);
2220 err += test_open(1, O_RDWR | O_CREAT | O_TRUNC, 0600);
2221 err += test_open(0, O_RDONLY | O_CREAT, 0600);
2222 err += test_open(0, O_RDONLY | O_CREAT, 0400);
2223 err += test_open(0, O_RDONLY | O_CREAT, 0200);
2224 err += test_open(0, O_RDONLY | O_CREAT, 0000);
2225 err += test_open(0, O_WRONLY | O_CREAT, 0600);
2226 err += test_open(0, O_WRONLY | O_CREAT, 0400);
2227 err += test_open(0, O_WRONLY | O_CREAT, 0200);
2228 err += test_open(0, O_WRONLY | O_CREAT, 0000);
2229 err += test_open(0, O_RDWR | O_CREAT, 0400);
2230 err += test_open(0, O_RDWR | O_CREAT, 0200);
2231 err += test_open(0, O_RDWR | O_CREAT, 0000);
2232 err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0600);
2233 err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0600);
2234 err += test_open(0, O_RDWR | O_CREAT | O_EXCL, 0000);
2235 err += test_open(1, O_RDWR | O_CREAT | O_EXCL, 0000);
2236 err += test_open_acc(O_RDONLY, 0600, 0);
2237 err += test_open_acc(O_WRONLY, 0600, 0);
2238 err += test_open_acc(O_RDWR, 0600, 0);
2239 err += test_open_acc(O_RDONLY, 0400, 0);
2240 err += test_open_acc(O_WRONLY, 0200, 0);
2242 err += test_open_acc(O_RDONLY | O_TRUNC, 0400, EACCES);
2243 err += test_open_acc(O_WRONLY, 0400, EACCES);
2244 err += test_open_acc(O_RDWR, 0400, EACCES);
2245 err += test_open_acc(O_RDONLY, 0200, EACCES);
2246 err += test_open_acc(O_RDWR, 0200, EACCES);
2247 err += test_open_acc(O_RDONLY, 0000, EACCES);
2248 err += test_open_acc(O_WRONLY, 0000, EACCES);
2249 err += test_open_acc(O_RDWR, 0000, EACCES);
2251 err += test_create_ro_dir(O_CREAT);
2252 err += test_create_ro_dir(O_CREAT | O_EXCL);
2253 err += test_create_ro_dir(O_CREAT | O_WRONLY);
2254 err += test_create_ro_dir(O_CREAT | O_TRUNC);
2255 err += test_copy_file_range();
2256 err += test_statx();
2258 err += test_create_tmpfile();
2259 err += test_create_and_link_tmpfile();
2268 fprintf(stderr,
"%i tests failed\n", -err);
2272 return check_unlinked_testfiles();