producers-consumers/src/driver.c

90 lines
2.7 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <sys/shm.h>
#include <unistd.h>
#include "shared.h"
int CheckArgumentPosition(int argc, char* argv[], char letter);
void CreateChildForks(int forkAmount, int forkType, int sharedID);
int GetSplitAmount(int argc, char* argv[], int forkType);
// Checks for producer and consumer arguments, creates shared memory,
// then creates forks sending the sharedID as an argument.
int main(int argc, char* argv[])
{
int producerAmount = GetSplitAmount(argc, argv, 0);
int consumerAmount = GetSplitAmount(argc, argv, 1);
int sharedID = shmget(IPC_CREAT | (key_t)1243, sizeof(SharedStruct), IPC_CREAT | 0666);
if (sharedID < 0)
{
fprintf(stderr, "Shmget failed\n");
exit(1);
}
SharedStruct* sharedMem = shmat(sharedID, NULL, 0);
SharedStructInit(sharedMem, producerAmount, consumerAmount);
CreateChildForks(producerAmount, 0, sharedID);
CreateChildForks(consumerAmount, 1, sharedID);
return 0;
}
// Checks for argument based on passed in letter.
int CheckArgumentPosition(int argc, char* argv[], char letter)
{
char argumentHyphen = '-';
char argumentLetter = letter;
for (int i = 1; i < argc; i++)
{
if ((*(argv[i]) == argumentHyphen) && (*(argv[i]+1) == argumentLetter))
{
return i;
}
}
return -1;
}
// Function creates an amount of children based on given type.
// forkAmount: Amount of children to create.
// forkType: 0 for creating producers, non-zero for consumers.
// sharedID: ID number of shared memory.
void CreateChildForks(int forkAmount, int forkType, int sharedID)
{
int forkID;
for (int i = 0; i < forkAmount; i++)
{
forkID = fork();
if (forkID < 0)
{
fprintf(stderr, "fork failed\n");
exit(1);
}
if (forkID == 0)
break;
}
if (forkID != 0)
return;
char sharedIDStr[16];
sprintf(sharedIDStr, "%d", sharedID);
if (forkType == 0)
execlp("./producer.out", "./producer.out", sharedIDStr, NULL);
if (forkType != 0)
execlp("./consumer.out", "./consumer.out", sharedIDStr, NULL);
exit(0);
}
// Takes in argc, argv, and type of fork to check for.
// forkType: 0 for creating producers, non-zero for consumers.
int GetSplitAmount(int argc, char* argv[], int forkType)
{
char letter;
int position;
if (forkType == 0)
letter = 'p';
if (forkType != 0)
letter = 'c';
position = CheckArgumentPosition(argc, argv, letter);
if (position == -1)
return 1;
return StringToNumber(argv[position+1]);
}