#define _GNU_SOURCE
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void)
{
    long page_size = sysconf(_SC_PAGESIZE);
    if (page_size < 64) {
        fputs("could not obtain page size\n", stderr);
        return EXIT_FAILURE;
    }
    char *shared = mmap(NULL, (size_t)page_size, PROT_READ | PROT_WRITE,
                        MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    if (shared == MAP_FAILED) {
        perror("mmap");
        return EXIT_FAILURE;
    }
    pid_t child = fork();
    if (child == -1) {
        perror("fork");
        munmap(shared, (size_t)page_size);
        return EXIT_FAILURE;
    }
    if (child == 0) {
        const char message[] = "written by the child";
        memcpy(shared, message, sizeof(message));
        _exit(EXIT_SUCCESS);
    }
    int status;
    pid_t result;
    do {
        result = waitpid(child, &status, 0);
    } while (result == -1 && errno == EINTR);
    if (result == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
        fputs("child did not finish successfully\n", stderr);
        munmap(shared, (size_t)page_size);
        return EXIT_FAILURE;
    }
    puts(shared);
    if (munmap(shared, (size_t)page_size) == -1) {
        perror("munmap");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
