/* Reproducable steps
gcc -g main.c -o app1
gcc -g app2.c -o app2
fn=/tmp/uB2kCDFlDoRA56gdeuvOVKbL1KHXxMhDXc3pFnhjbhc
dd if=/dev/zero of=$fn count=5120 bs=4096; ./app1 $fn 1 | ./app2 $fn
You'll see "Result was 72" instead of "Result was 0"
(app 2 modifies $fn so we'll need dd again)
dd if=/dev/zero of=$fn count=5120 bs=4096; ./app1 $fn 0 | ./app2 $fn
You'll see the desired "Result was 0"
In app2.c uncomment/comment line 13 and 12
gcc app2.c -o app2
Now this will have a bus error and "Result" line will not print
dd if=/dev/zero of=$fn count=5120 bs=4096; ./app1 $fn 1 | ./app2 $fn
read is unaffected
dd if=/dev/zero of=$fn count=5120 bs=4096; ./app1 $fn 0 | ./app2 $fn
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
	//a.out filename 1
	if (argc != 3) {
		fprintf(stderr, "Bad args\n");
		return 1;
	}
	
	int fd = open(argv[1], O_RDONLY);
	struct stat s={0};
	fstat(fd, &s);
	char*p;
	if (argv[2][0] == '1')
		p = (char*)mmap(0, s.st_size, PROT_READ , MAP_PRIVATE, fd, 0);
	else {
		p = (char*)malloc(s.st_size);
		read(fd, p, s.st_size);
	}
	write(2, "Sleeping\n", 9);
	write(1, "Sleeping\n", 9); //Triggers the other app to write
	sleep(1);
	write(2, "Waking\n", 7);

	//read first byte of every 4k page
	int sum = 0;
	for (long i=0; i<s.st_size; i+=4096) {
		if (p[i] != 0) {
			int z=0;
		}
		sum += p[i];
	}
	fprintf(stderr, "Result was %d\n", sum);
	return 0;
}

