#include <math.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/wait.h>

void filter(int p)
{
	while(1){
		int n;
		ssize_t nb_read = read(STDIN_FILENO,&n,sizeof(int));
		if (nb_read <= 0)
			break;
		if ((n%p) !=0)
			write(STDOUT_FILENO,&n,sizeof(int));
	}
	exit(0);
}

void seq(int N)
{
	for(int i = 2;i <= N; i++)
		write(STDOUT_FILENO,&i,sizeof(i));
	exit(0);
}

int master()
{
	int count_primes = 0;
	while(1){
		ssize_t nb_read;
		pid_t p;
		int t[2];
		int prime;
		nb_read = read(STDIN_FILENO,&prime,sizeof(int));
		if (nb_read <=0)
			break;
		printf("prime = %d\n",prime);
		count_primes  ++;
		assert(pipe(t) == 0);
		p = fork();
		if (p == 0){
			close(t[0]);
			dup2(t[1],STDOUT_FILENO);
			close(t[1]);
			filter(prime);

		}
		close(t[1]);
		dup2(t[0],STDIN_FILENO);
		close(t[0]);

	}
	return count_primes;
}

int main(int argc, char *argv[])
{
	int t[2];
	pid_t p;
	struct sigaction sa = {0};

	int max = (int)strtol(argv[1],NULL,0);
	sa.sa_flags = SA_NOCLDWAIT;
	sigemptyset(&sa.sa_mask);

	sigaction(SIGCHLD, &sa , NULL);
	assert(pipe(t) == 0);

	p = fork();

	if (p == 0){
		close(t[0]);
		dup2(t[1],STDOUT_FILENO);
		close(t[1]);
		seq(max);
	}
	close(t[1]);
	dup2(t[0],STDIN_FILENO);
	close(t[0]);
	printf("densité = %lf\n",master()*1.0/max);
	return 0;
}
