8static int child_layout(
unsigned char* mapping,
int fd,
int command,
int status) {
10 const size_t page = rp_page;
12 CHECK(rp_matches(mapping, 0, page, 0) && rp_matches(mapping + page, 5 * page, page, 0) &&
13 rp_matches(mapping + 2 * page, 2 * page, 2 * page, 0));
14 CHECK(!rp_send(status,
'R') && !rp_receive(command,
'G'));
15 CHECK(mapping[2 * page + 53] == 0xd4);
16 mapping[2 * page + 53] = rp_pattern(2 * page + 53);
17 CHECK(rp_matches(mapping, 0, page, 0) && rp_matches(mapping + page, 5 * page, page, 0) &&
18 rp_matches(mapping + 2 * page, 2 * page, 2 * page, 0));
19 CHECK(!remap_file_pages(mapping + 2 * page, page, 0, 7, 0));
20 CHECK(rp_matches(mapping + 2 * page, 7 * page, page, 0));
21 mapping[page + 33] = 0xe6;
22 CHECK(!rp_send(status,
'D') && !rp_receive(command,
'F'));
27static int last_descriptor(
int backend) {
29 struct rp_file file = {.fd = -1};
30 int command[2] = {-1, -1}, status[2] = {-1, -1};
32 const size_t page = rp_page;
33 unsigned char *mapping = MAP_FAILED, *alias = MAP_FAILED, *moved = MAP_FAILED;
34 CHECK(!rp_create(&file, backend));
35 mapping = mmap(NULL, 4 * page, PROT_READ | PROT_WRITE, MAP_SHARED, file.fd, 0);
36 alias = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_SHARED, file.fd, 5 * page);
37 CHECK(mapping != MAP_FAILED && alias != MAP_FAILED);
38 CHECK(!remap_file_pages(mapping + page, page, 0, 5, 0));
39 CHECK(!pipe(command) && !pipe(status));
40 CHECK((child = fork()) >= 0);
45 int result = child_layout(mapping, file.fd, command[0], status[1]);
47 _exit(result ? 1 : 0);
53 CHECK(!rp_receive(status[0],
'R'));
55 CHECK(!unlink(file.path));
58 CHECK(!close(file.fd));
60 CHECK(!remap_file_pages(mapping, 4 * page, 0, 1, 0));
61 CHECK(rp_matches(mapping, page, 4 * page, 0));
62 mapping[page + 53] = 0xd4;
63 CHECK(!rp_send(command[1],
'G') && !rp_receive(status[0],
'D'));
64 CHECK(alias[33] == 0xe6 && rp_matches(mapping, page, 4 * page, 0));
65 alias[33] = rp_pattern(5 * page + 33);
66 CHECK(!rp_send(command[1],
'F'));
67 int child_status = rp_reap(child, 5000);
69 CHECK(child_status == 0);
71 CHECK(!mprotect(mapping + page, page, PROT_READ));
72 moved = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
73 CHECK(moved != MAP_FAILED);
74 CHECK(mremap(mapping + page, page, page, MREMAP_MAYMOVE | MREMAP_FIXED, moved) == moved);
75 CHECK(rp_matches(moved, 2 * page, page, 0));
76 CHECK(!remap_file_pages(moved, page, 0, 6, MAP_NONBLOCK));
77 CHECK(!madvise(moved, page, MADV_DONTNEED) && rp_matches(moved, 6 * page, page, 0));
78 CHECK(!mprotect(moved, page, PROT_READ | PROT_WRITE));
79 CHECK(!remap_file_pages(mapping, page, 0, 6, 0));
81 CHECK(mapping[55] == 0xba && rp_matches(mapping + 2 * page, 3 * page, 2 * page, 0));
87 for (
int n = 0; n < 2; ++n) {
93 if (moved != MAP_FAILED)
95 if (alias != MAP_FAILED)
97 if (mapping != MAP_FAILED)
98 munmap(mapping, 4 * page);
101 fprintf(stderr,
"REMAP-FILE-PAGES-CONTRACT: lifetime backend=%d\n", backend);
105int rp_lifetime(
void) {
106 for (
int backend = RP_MEMFD; backend <= RP_EXT2; ++backend) {
107 if (last_descriptor(backend))