10 // Based on a test by Steven Stewart-Gallus, see 342040
11 int fork_routine(void *arg
)
13 write(1, "fork_routine\n", 13);
19 long page_size
= sysconf(_SC_PAGE_SIZE
);
20 assert(page_size
!= -1);
22 /* We need an extra page for signals */
23 long stack_size
= sysconf(_SC_THREAD_STACK_MIN
) + page_size
;
24 assert(stack_size
!= -1);
26 size_t stack_and_guard_size
= page_size
+ stack_size
+ page_size
;
27 void *child_stack
= mmap(
28 NULL
, stack_and_guard_size
, PROT_READ
| PROT_WRITE
,
29 MAP_PRIVATE
| MAP_ANONYMOUS
| MAP_GROWSDOWN
, -1, 0);
30 if (NULL
== child_stack
) {
35 /* Guard pages are shared between the stacks */
36 if (-1 == mprotect((char *)child_stack
, page_size
, PROT_NONE
)) {
41 if (-1 == mprotect((char *)child_stack
+ page_size
+ stack_size
,
42 page_size
, PROT_NONE
)) {
47 void *stack_start
= (char *)child_stack
+ page_size
+ stack_size
;
49 printf("stack_start %p page_size %d stack_size %d\n",
50 stack_start
, (int)page_size
, (int)stack_size
);
51 write(1, "parent before clone\n", 20);
53 clone(fork_routine
, stack_start
,
54 SIGCHLD
| CLONE_VFORK
| CLONE_VM
, NULL
);
55 write(1, "parent after clone\n", 19);
63 switch (waitpid(child
, &xx
, 0)) {