12int ef_mutations(
void) {
13 int failed = 0, fd = -1, other = -1, probe = -1;
14 char path[PATH_MAX] = {0}, alias[PATH_MAX] = {0};
15 unsigned char* map = MAP_FAILED;
16 CHECK((fd = ef_create(
"mutations", path)) >= 0);
18 snprintf(alias,
sizeof(alias),
"%s/hardlink", ef_directory);
19 CHECK(!link(path, alias));
21 CHECK((other = open(ef_ext2 ? alias : path, O_RDWR | O_CLOEXEC)) >= 0);
22 map = mmap(NULL, 3 * ef_page, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
23 CHECK(map != MAP_FAILED && map[0] == 0x31);
24 CHECK(lseek(fd, 17, SEEK_SET) == 17);
25 CHECK(write(fd,
"x", 1) == -1 && errno == ETXTBSY);
26 CHECK(lseek(fd, 0, SEEK_CUR) == 17);
27 CHECK(pwrite(other,
"x", 1, ef_page + 3) == -1 && errno == ETXTBSY);
28 CHECK(ftruncate(other, 0) == -1 && errno == ETXTBSY);
29 CHECK(ftruncate(fd, 4 * ef_page) == -1 && errno == ETXTBSY);
30 CHECK(fallocate(other, 0, 0, 4 * ef_page) == -1 && errno == ETXTBSY);
31 probe = open(ef_ext2 ? alias : path, O_WRONLY | O_TRUNC);
32 CHECK(probe == -1 && errno == ETXTBSY);
33 CHECK((probe = open(path, O_WRONLY | O_CLOEXEC)) >= 0);
34 CHECK(write(probe,
"x", 1) == -1 && errno == ETXTBSY);
36 unsigned char bytes[32];
37 CHECK(!fstat(other, &metadata) && metadata.st_size == (off_t)(3 * ef_page));
38 CHECK(pread(other, bytes,
sizeof(bytes), ef_page) ==
sizeof(bytes));
39 for (
size_t n = 0; n <
sizeof(bytes); ++n)
40 CHECK(bytes[n] == 0x31);
41 CHECK(!munmap(map, 3 * ef_page));
43 CHECK(pwrite(other,
"y", 1, 0) == 1 && !ftruncate(fd, ef_page));
45 if (map != MAP_FAILED)
46 munmap(map, 3 * ef_page);
60int ef_lifetime(
void) {
61 int failed = 0, fd = -1, ready[2] = {-1, -1}, gate[2] = {-1, -1};
62 char path[PATH_MAX] = {0};
63 unsigned char* map = MAP_FAILED;
65 CHECK((fd = ef_create(
"lifetime", path)) >= 0);
66 map = mmap(NULL, 3 * ef_page, PROT_READ, MAP_PRIVATE, fd, 0);
67 CHECK(map != MAP_FAILED);
68 CHECK(!mprotect(map, 3 * ef_page, PROT_READ | PROT_EXEC));
69 CHECK(!munmap(map + ef_page, ef_page));
70 CHECK(!mprotect(map, ef_page, PROT_READ));
71 CHECK(!pipe(ready) && !pipe(gate));
72 CHECK((child = fork()) >= 0);
77 if (ef_send(ready[1],
'r') || ef_receive(gate[0],
'g') || map[2 * ef_page] != 0x31 ||
78 munmap(map, ef_page) || mprotect(map + 2 * ef_page, ef_page, PROT_READ) ||
79 munmap(map + 2 * ef_page, ef_page))
87 CHECK(!ef_receive(ready[0],
'r'));
88 CHECK(!munmap(map, ef_page));
89 CHECK(pwrite(fd,
"x", 1, 0) == -1 && errno == ETXTBSY);
90 CHECK(!munmap(map + 2 * ef_page, ef_page));
92 CHECK(pwrite(fd,
"x", 1, 0) == -1 && errno == ETXTBSY);
93 CHECK(!ef_send(gate[1],
'g'));
94 int status = ef_reap(child);
96 CHECK(!status && pwrite(fd,
"x", 1, 0) == 1);
102 if (map != MAP_FAILED) {
103 munmap(map, ef_page);
104 munmap(map + 2 * ef_page, ef_page);
106 for (
int n = 0; n < 2; ++n) {
119int ef_conflicts(
void) {
120 int failed = 0, fd = -1, readonly = -1;
121 char path[PATH_MAX] = {0};
122 void *shared = MAP_FAILED, *
private = MAP_FAILED, *probe = MAP_FAILED;
123 CHECK((fd = ef_create(
"conflicts", path)) >= 0);
124 CHECK((readonly = open(path, O_RDONLY | O_CLOEXEC)) >= 0);
125 shared = mmap(NULL, ef_page, PROT_READ, MAP_SHARED, fd, 0);
126 CHECK(shared != MAP_FAILED);
127 private = mmap(NULL, ef_page, PROT_READ, MAP_PRIVATE, fd, 0);
128 CHECK(
private != MAP_FAILED);
129 probe = mmap(NULL, ef_page, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
130 CHECK(probe == MAP_FAILED && errno == ETXTBSY);
131 CHECK(mprotect(
private, ef_page, PROT_READ | PROT_EXEC) == -1 && errno == ETXTBSY);
132 CHECK(pwrite(fd,
"x", 1, 0) == 1);
133 CHECK(!mprotect(shared, ef_page, PROT_READ | PROT_WRITE));
134 ((
volatile unsigned char*)shared)[0] = 0x32;
135 CHECK(!munmap(shared, ef_page));
137 CHECK(!mprotect(
private, ef_page, PROT_READ | PROT_EXEC));
138 probe = mmap(NULL, ef_page, PROT_READ, MAP_SHARED, fd, 0);
139 CHECK(probe == MAP_FAILED && errno == ETXTBSY);
140 probe = mmap(NULL, ef_page, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
141 CHECK(probe == MAP_FAILED && errno == ETXTBSY);
142 shared = mmap(NULL, ef_page, PROT_READ, MAP_SHARED, readonly, 0);
143 CHECK(shared != MAP_FAILED);
144 CHECK(mprotect(shared, ef_page, PROT_READ | PROT_WRITE) == -1 && errno == EACCES);
145 CHECK(!munmap(shared, ef_page) && !munmap(
private, ef_page));
146 shared =
private = MAP_FAILED;
147 CHECK(pwrite(fd,
"x", 1, 0) == 1);
148 probe = mmap(NULL, ef_page, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0);
149 CHECK(probe != MAP_FAILED);
150 ((
volatile unsigned char*)probe)[0] = 0x34;
151 CHECK(pwrite(fd,
"x", 1, 0) == 1);
153 if (probe != MAP_FAILED)
154 munmap(probe, ef_page);
155 if (shared != MAP_FAILED)
156 munmap(shared, ef_page);
157 if (
private != MAP_FAILED)
158 munmap(
private, ef_page);
168int ef_ordinary(
void) {
169 int failed = 0, fd = -1;
170 char path[PATH_MAX] = {0};
171 unsigned char* map = MAP_FAILED;
172 CHECK((fd = ef_create(
"ordinary", path)) >= 0);
173 map = mmap(NULL, 3 * ef_page, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
174 CHECK(map != MAP_FAILED && map[0] == 0x31);
176 CHECK(pwrite(fd,
"z", 1, 1) == 1);
178 CHECK(pread(fd, &
byte, 1, 0) == 1 &&
byte == 0x31);
179 CHECK(map[0] == 0x43);
180 CHECK(!ftruncate(fd, ef_page) && !ftruncate(fd, 3 * ef_page));
181 CHECK(map[2 * ef_page] == 0 && map[0] == 0x43);
183 if (map != MAP_FAILED)
184 munmap(map, 3 * ef_page);