#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/user.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main (int argc, char *argv[])
{
	int fd, ret;
	char data[PAGE_SIZE];
	bool write_goes_first = false;

        if (NULL != getenv("SF_WRITE_GOES_FIRST")) {
                write_goes_first = true;
        }

	if (false == write_goes_first) {
		sleep(1); // wait for read
	}

	fd = open(argv[2], O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
	if (-1 == fd) {
		perror("Could not create file");
		exit(EXIT_FAILURE);
	}

	ret = posix_fallocate(fd, 0, PAGE_SIZE);
	if (0 != ret) {
		fprintf(stderr, "Could not allocate space in file: %s\n", strerror(ret));
		exit(EXIT_FAILURE);
	}

	void *ptr = mmap(NULL, PAGE_SIZE, PROT_WRITE, MAP_SHARED, fd, 0);
	if (MAP_FAILED == ptr) {
		perror("Could not mmap file");
		exit(EXIT_FAILURE);
	}

	close(fd);

	fd = open(argv[1], O_RDONLY);
	if (-1 == fd) {
		perror("Could not open file");
		exit(EXIT_FAILURE);
	}

	ret = read(fd, data, PAGE_SIZE);
	if (-1 == ret) {
		perror("Could not read file");
		exit(EXIT_FAILURE);
	}

	close(fd);

	memcpy(ptr, data, strlen(data));

	ret = msync(ptr, PAGE_SIZE, MS_SYNC);
	if (-1 == ret) {
		perror("Could not msync file");
		exit(EXIT_FAILURE);
	}

	munmap(ptr, 4069);

	exit(EXIT_SUCCESS);
}
