I am making a program that finds all of the products of two prime numbers within a given range and prints them out. The program works fine with having the numbers print if I check them normally in each child process. The problem comes about when I try to write the number to the pipe instead of just printing it. I honestly have been working on this for days now and getting nowhere.
Below, I have posted the working code that prints out the products of two primes. I have the write to the pipe commented out as well as the read. Please let me know if you can help me out!
/*
progname 4 2 1000, should create 4 child processes that will find
the product of two primes between 2 and 1000 and print them to the screen.
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
int strtoi(char* str);
void findProductsOfTwoPrimes(int numChildren, int rangeMin, int rangeMax);
void printArray(int* array, int size);
int isSemiprime(int number);
int fd[2];
int main(int argc, char* argv[]) {
/*________________________________
| -------- Parameters -------- |
| argv[0]: progname |
| argv[1]: number children (int) |
| argv[2]: range min (int) |
| argv[3]: range max (int) |
|_________________________________|*/
int numChildren, rangeMin, rangeMax;
switch (argc) {
case 2:
printf("%s", "Provide Range\nInvalid Usage: progname numChildren(int) rangeMin(int) rangeMax(int)\n");
break;
case 3:
printf("%s", "Provide Range Max\nInvalid Usage: progname numChildren(int) rangeMin(int) rangeMax(int)\n");
break;
case 4:
/*Retrieve values from argument array*/
numChildren = strtoi(argv[1]);
rangeMin = strtoi(argv[2]);
rangeMax = strtoi(argv[3]);
pipe(fd);
findProductsOfTwoPrimes(numChildren, rangeMin, rangeMax);
break;
default:
printf("%s", "Invalid Usage: progname numChildren(int) rangeMin(int) rangeMax(int)\n");
break;
};
exit(0);
}
/*_________________________________________________
| This function converts a char* to an integer if |
| possible. |
|__________________________________________________|*/
int strtoi(char* str) {
/* set errno & escape check var*/
errno = 0;
char* p;
/* attemp conversion to long */
long longVal = strtol(str, &p, 10);
if (*p != '\0' || errno != 0) {
/*print error*/
printf("%s", "Please provide correct usage: progname numChildren(int) rangeMin(int) rangeMax(int)\n");
return -1;
}
/* check if long is in range of int */
if (longVal < INT_MIN || longVal > INT_MAX) {
return -1;
}
int intVal = longVal;
return intVal;
}
void findProductsOfTwoPrimes(int numChildren, int rangeMin, int rangeMax) {
int readResult;
/* if we have valid range */
if ((rangeMax - rangeMin) > 0) {
/* get size from input range*/
int size = rangeMax - rangeMin + 1;
/* allocate space for an array */
int* numbers = malloc(size * sizeof(*numbers));
if (!numbers) {
printf("%s", "Error allocating memory\n");
}
/* fill array */
int i;
for (i = 0; i < size; i++) {
numbers[i] = i + rangeMin;
}
/*printArray(numbers, size); debugging*/
/* see if we are evenly divisable */
int childrenEvenlyFit;
if (size % numChildren == 0) {
childrenEvenlyFit = 1;
}
else {
childrenEvenlyFit = 0;
}
if (childrenEvenlyFit == 1) {
/* define fork variables */
int j, pid = 1, childCount = 0;
/* get the number of elements each child is responsible for */
int ourPortionSize = size / numChildren;
close(fd[0]);
for (j = 0; j < numChildren; j++) {
if (pid != 0) {
childCount++;
pid = fork();
if (pid == 0) { /* we are a child */
/* we have to use childCount to see where in the array we are checking */
/* array starts at 0, ends at size */
/* childCount starts at 0, ends at numChildren */
/* printf("child %d \n", childCount); debugging */
/* get the range of elements respective to portion size and childCount */
int rangeMax = (childCount * ourPortionSize) - 1;
int rangeMin = (childCount * ourPortionSize) - ourPortionSize;
int k;
for (k = rangeMin; k <= rangeMax; k++) {
if (isSemiprime(numbers[k])) {
printf("%d\n", numbers[k]);
//write(fd[1], &numbers[k], sizeof(numbers[k]));
}
}
}
}
}
//read(fd[0], &readResult, sizeof(readResult));
//printf("Result: %d\n", readResult);
}
else {
printf("%s", "Provide child number that goes evenly into range...\n");
}
/* deallocate array */
free(numbers);
}
else {
printf("%s", "Invalid Range\n");
}
}
/*_________________________________________________
| This function prints a given array with an input |
| integer size |
|__________________________________________________|*/
void printArray(int* array, int size) {
printf("[");
int i;
for (i = 0; i < size - 1; i++) {
printf("%i, ", array[i]);
}
if (size >= 1) printf("%i", array[size - 1]);
printf("]\n");
}
/*_________________________________________________
| This function checks if an integer is semiprime |
|__________________________________________________|*/
int isSemiprime(int number) {
int count = 0;
int i;
for (i = 2; count < 2 && i * i <= number; i++) {
while (number % i == 0) {
number /= i, ++count;
}
}
if (number > 1) {
++count;
}
/* returns 1 if semiprime, 0 if not */
return count == 2;
}