#include <sys/time.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>

/* Creates n subprocesses, each computing a sum [0, x],
   where x is a random number. Results are read through
   pipes */

void *ecalloc(size_t nelem, size_t elsize);

int main(int argc, char *argv[]) {
struct timeval tv;
int (*pipe_fds)[2];
pid_t *pids;
int numprocs, i, j, readyFiles;
int *limits;
long *results;
int hasError = 0;
fd_set theFds, readFds, errorFds;
int maxfd = -1;

if (argc == 1) {
	fprintf(stderr, "provide the number of procs\n");
	return 1;
}
numprocs = atoi(argv[1]);
if (numprocs <= 0) {
	fprintf(stderr, "numprocs must be > 0\n");
	return 1;
}

gettimeofday(&tv, NULL);
srand(tv.tv_usec);

pipe_fds = ecalloc(numprocs, sizeof(int [2]));
pids = ecalloc(numprocs, sizeof(pid_t));
limits = ecalloc(numprocs, sizeof(int));
results = ecalloc(numprocs, sizeof(long));
FD_ZERO(&theFds);

for (i = 0; i < numprocs; i++) {
	if (pipe(pipe_fds[i]) < 0) {
		perror("cannot create pipe pair");
		hasError = 1;
		break;
	}
	while ((limits[i] = rand()) == 0) ;
	if ((pids[i] = fork()) == -1) {
		hasError = 1;
		close(pipe_fds[i][0]);
		close(pipe_fds[i][1]);
		break;
	}
	if (pids[i] > 0) { /* parent */
		/* O KALOS MPAMPAS EDW */
	}
	else { /* Child process */
		sleep(rand() % 3);
		/* TO ATAKTO PAIDI EDW */
		exit(0);
	}
}

/* Parent done with creating children */
if (hasError == 1) {
	printf("Successfully created %d out of %d procs\n", i - 1, numprocs);
	numprocs = i - 1;
}
else
	printf("Successfully created all %d procs\n", numprocs);

i = numprocs;
while (i != 0) {
	/* SYLLOGH APOTELESMATWN KAI STATUS APO TA PAIDIA */
}

for (i = 0; i < numprocs; i++) {
	if (results[i] == -1)
		printf("Child %d (pid = %ld) failed to compute/return sum\n",
			i, (long)(pids[i]));
	else
		printf("Child %d (pid = %ld) computed: sum([1..%d]) = %ld\n",
			i, (long)(pids[i]), limits[i], results[i]);
}
return 0;
}


void *ecalloc(size_t nelem, size_t elsize) {

void *res = calloc(nelem, elsize);
if (res == NULL) {
	perror("Cannot allocate memory");
	exit(2);
}
return res;
}

