8static int private_child(
int fd,
unsigned char*
private,
unsigned char* borrowed,
int ready,
11 const size_t page = fr_page, length = 4 * page, cut = page + 137;
12 unsigned char* independent = mmap(NULL, 3 * page, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page);
13 CHECK(independent != MAP_FAILED &&
private[23] == 0xc1 &&
private[2 * page + 19] == 0xc2);
15 private[2 * page + 19] = 0xd2;
16 CHECK(fr_matches(independent, page, 3 * page, 0) && fr_matches(borrowed, page, 3 * page, 0));
17 CHECK(!fr_resident(
private, 4, 15,
"child private before shrink") &&
18 !fr_resident(independent, 3, 7,
"independent child alias before shrink"));
19 CHECK(!fr_send(ready,
'r') && !fr_receive(gate,
's'));
21 CHECK(!fr_resident(
private, 4, 3,
"child private after shrink") &&
22 !fr_resident(borrowed, 3, 1,
"inherited child alias after shrink") &&
23 !fr_resident(independent, 3, 1,
"independent child alias after shrink"));
24 CHECK(
private[23] == 0xd1 && fr_matches(
private, 0, 23, 0) &&
25 fr_matches(
private + 24, 24, cut - 24, 0));
26 CHECK(fr_matches(
private + cut, cut, 2 * page - cut, 1));
27 CHECK(fr_matches(independent, page, 137, 0) && fr_matches(independent + 137, cut, page - 137, 1));
28 CHECK(fr_matches(borrowed, page, 137, 0) && fr_matches(borrowed + 137, cut, page - 137, 1));
29 CHECK(!fr_fault(
private + 2 * page) && !fr_fault(independent + page));
30 CHECK(!fr_send(ready,
's') && !fr_receive(gate,
'g'));
32 CHECK(!fr_resident(
private, 2, 3,
"child private prefix after regrowth") &&
33 !fr_resident(independent, 1, 1,
"independent child prefix after regrowth"));
34 CHECK(
private[23] == 0xd1 && fr_matches(
private + cut, cut, length - cut, 1));
35 CHECK(fr_matches(independent + 137, cut, length - cut, 1) &&
36 fr_matches(borrowed + 137, cut, length - cut, 1));
37 independent[257] = 0xe7;
38 CHECK(
private[page + 257] == 0xe7 && borrowed[257] == 0xe7);
39 CHECK(!fr_send(ready,
'g'));
41 if (independent != MAP_FAILED)
42 munmap(independent, 3 * page);
46int fr_private(
int backend) {
47 int failed = 0, ready[2] = {-1, -1}, gate[2] = {-1, -1};
48 struct fr_file file = {.fd = -1};
49 const size_t page = fr_page, length = 4 * page, cut = page + 137;
51 unsigned char *
private = MAP_FAILED, *borrowed = MAP_FAILED;
53 CHECK(!fr_create(&file, backend));
54 private = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE, file.fd, 0);
55 borrowed = mmap(NULL, 3 * page, PROT_READ, MAP_PRIVATE, file.fd, page);
56 CHECK(
private != MAP_FAILED && borrowed != MAP_FAILED);
57 CHECK(fr_matches(
private, 0, length, 0) && fr_matches(borrowed, page, 3 * page, 0));
59 private[2 * page + 19] = 0xc2;
60 CHECK(!fr_contents(file.fd, 0, length, 0));
61 CHECK(!pipe(ready) && !pipe(gate) && (child = fork()) >= 0);
66 int result = private_child(file.fd,
private, borrowed, ready[1], gate[0]);
68 _exit(result ? 1 : 0);
70 CHECK(!close(ready[1]) && !close(gate[0]));
71 ready[1] = gate[0] = -1;
72 CHECK(!fr_receive(ready[0],
'r'));
73 CHECK(
private[23] == 0xc1 &&
private[2 * page + 19] == 0xc2);
74 CHECK(!fr_resident(
private, 4, 15,
"parent private before shrink"));
75 CHECK(!ftruncate(file.fd, cut));
76 CHECK(!fr_resident(
private, 4, 3,
"parent private after shrink") &&
77 !fr_resident(borrowed, 3, 1,
"parent borrowed after shrink"));
78 CHECK(
private[23] == 0xc1 && fr_matches(
private, 0, 23, 0) &&
79 fr_matches(
private + 24, 24, cut - 24, 0));
80 CHECK(fr_matches(
private + cut, cut, 2 * page - cut, 1) &&
81 fr_matches(borrowed + 137, cut, page - 137, 1));
82 CHECK(!fr_send(gate[1],
's') && !fr_receive(ready[0],
's'));
83 CHECK(!fr_fault(
private + 2 * page));
84 CHECK(!ftruncate(file.fd, length));
85 CHECK(!fr_resident(
private, 2, 3,
"parent private prefix after regrowth"));
86 CHECK(
private[23] == 0xc1 && fr_matches(
private + cut, cut, length - cut, 1));
87 CHECK(!fr_send(gate[1],
'g') && !fr_receive(ready[0],
'g'));
88 CHECK(
private[23] == 0xc1 &&
private[page + 257] == 0xe7 && borrowed[257] == 0xe7);
89 CHECK(pread(file.fd, &
byte, 1, page + 257) == 1 &&
byte == 0xe7);
90 int status = fr_reap(child, 5000);
98 for (
int n = 0; n < 2; ++n) {
104 if (borrowed != MAP_FAILED)
105 munmap(borrowed, 3 * page);
106 if (
private != MAP_FAILED)
107 munmap(
private, length);