8static int open_flags(
void) {
9 int failed = 0, writer = -1,
reader = -1;
10 struct fh_file file = {.fd = -1};
13 CHECK(!fh_create(&file));
14 writer = open_by_handle_at(file.fd, (
struct file_handle*)&file.handle,
15 O_WRONLY | O_APPEND | O_CLOEXEC | O_NONBLOCK | O_LARGEFILE);
17 CHECK(fcntl(writer, F_GETFD) & FD_CLOEXEC);
18 CHECK((fcntl(writer, F_GETFL) & (O_ACCMODE | O_APPEND | O_NONBLOCK)) ==
19 (O_WRONLY | O_APPEND | O_NONBLOCK));
20 CHECK(write(writer,
"Z", 1) == 1);
21 CHECK(!fstat(file.fd, &state) && state.st_size == 17);
22 CHECK(pread(file.fd, bytes, 1, 16) == 1 && bytes[0] ==
'Z');
23 reader = open_by_handle_at(file.fd, (
struct file_handle*)&file.handle, O_RDONLY);
26 CHECK(write(
reader,
"x", 1) == -1 && errno == EBADF);
28 writer = open_by_handle_at(file.fd, (
struct file_handle*)&file.handle, O_RDWR | O_TRUNC);
29 CHECK(writer >= 0 && !fstat(file.fd, &state) && state.st_size == 0);
30 CHECK(write(writer,
"new", 3) == 3);
31 CHECK(pread(
reader, bytes, 3, 0) == 3 && !memcmp(bytes,
"new", 3));
42 int failed = 0, root = -1, first = -1, second = -1, duplicate = -1, alias_fd = -1, path_fd = -1;
43 struct fh_file file = {.fd = -1};
45 char alias[224] = {0}, moved[224] = {0}, bytes[8];
46 struct stat state, reopened;
48 CHECK(!fh_create(&file));
49 CHECK(file.mount_id > 0 && file.handle.handle_bytes && file.handle.handle_bytes <= 128);
50 memset(&query, 0xa5,
sizeof(query));
51 query.handle_bytes = 0;
53 CHECK(name_to_handle_at(AT_FDCWD, file.path, (
struct file_handle*)&query, &mount_id, 0) == -1 &&
55 CHECK(query.handle_bytes == file.handle.handle_bytes && mount_id == file.mount_id);
56 for (
size_t n = 0; n <
sizeof(query.bytes); ++n)
57 CHECK(query.bytes[n] == 0xa5);
58 query.handle_bytes = file.handle.handle_bytes - 1;
60 CHECK(name_to_handle_at(AT_FDCWD, file.path, (
struct file_handle*)&query, &mount_id, 0) == -1 &&
61 errno == EOVERFLOW && query.handle_bytes == file.handle.handle_bytes);
62 query.handle_bytes =
sizeof(query.bytes);
63 CHECK(!name_to_handle_at(AT_FDCWD, file.path, (
struct file_handle*)&query, &mount_id, 0));
64 CHECK(fh_equal(&query, &file.handle));
65 root = open(
"/", O_RDONLY | O_DIRECTORY | O_CLOEXEC);
67 exact.handle_bytes =
sizeof(exact.bytes);
68 CHECK(!name_to_handle_at(root, file.path + 1, (
struct file_handle*)&exact, &mount_id, 0));
69 CHECK(fh_equal(&exact, &file.handle) && mount_id == file.mount_id);
70 path_fd = open(file.path, O_PATH | O_CLOEXEC);
71 CHECK(path_fd >= 0 && !fh_export(path_fd, &exact, &mount_id));
72 CHECK(fh_equal(&exact, &file.handle));
73 CHECK(lseek(file.fd, 7, SEEK_SET) == 7);
74 first = open_by_handle_at(root, (
struct file_handle*)&file.handle, O_RDONLY);
75 second = open_by_handle_at(file.fd, (
struct file_handle*)&file.handle, O_RDONLY);
76 CHECK(first >= 0 && second >= 0 && lseek(first, 0, SEEK_CUR) == 0);
77 CHECK(read(first, bytes, 2) == 2 && !memcmp(bytes,
"01", 2));
78 CHECK(lseek(second, 0, SEEK_CUR) == 0 && lseek(file.fd, 0, SEEK_CUR) == 7);
79 duplicate = dup(first);
80 CHECK(duplicate >= 0 && read(duplicate, bytes, 1) == 1 && bytes[0] ==
'2');
81 CHECK(lseek(first, 0, SEEK_CUR) == 3);
82 CHECK(!fstat(file.fd, &state) && !fstat(first, &reopened) && state.st_ino == reopened.st_ino);
83 snprintf(alias,
sizeof(alias),
"%s.alias", file.path);
84 snprintf(moved,
sizeof(moved),
"%s.moved", file.path);
85 CHECK(!link(file.path, alias) && !rename(file.path, moved));
86 snprintf(file.path,
sizeof(file.path),
"%s", moved);
88 alias_fd = open(alias, O_RDONLY | O_CLOEXEC);
89 CHECK(alias_fd >= 0 && !fh_export(alias_fd, &exact, &mount_id));
90 CHECK(fh_equal(&exact, &file.handle));
91 CHECK(!unlink(file.path));
94 second = open_by_handle_at(root, (
struct file_handle*)&file.handle, O_RDONLY);
95 CHECK(second >= 0 && pread(second, bytes, 4, 0) == 4 && !memcmp(bytes,
"0123", 4));
96 changed = file.handle;
97 changed.handle_type ^= 0x01000000;
99 CHECK(open_by_handle_at(root, (
struct file_handle*)&changed, O_RDONLY) == -1 && errno == ESTALE);
100 changed = file.handle;
101 changed.bytes[0] ^= 0x80;
103 CHECK(open_by_handle_at(root, (
struct file_handle*)&changed, O_RDONLY) == -1 && errno == ESTALE);
104 CHECK(!unlink(alias));
107 CHECK(open_by_handle_at(root, (
struct file_handle*)&file.handle, O_RDONLY) == -1 &&
109 CHECK(pread(first, bytes, 4, 0) == 4 && !memcmp(bytes,
"0123", 4));
110 CHECK(!open_flags());