static int readQueueLengthFromFifo(void) { int queue_length = 0; int fifo_fd = open(FIFO_NAME, O_RDWR); if(fifo_fd < 0) { deleteFifo(); // No checking needed, exits with error code. write(STDERR_FILENO, OPEN_ERROR, sizeof(OPEN_ERROR)); exit(EXIT_ERROR_CODE); } // Read the queue length. if(read(fifo_fd, (void*)&queue_length, sizeof(queue_length)) != sizeof(queue_length)) { deleteFifo(); // No checking needed, exits with error code. write(STDERR_FILENO, READ_ERROR, sizeof(READ_ERROR)); exit(EXIT_ERROR_CODE); } // Close FIFO. if(close(fifo_fd) < 0) { deleteFifo(); // No checking needed, exits with error code. write(STDERR_FILENO, CLOSE_ERROR, sizeof(CLOSE_ERROR)); exit(EXIT_ERROR_CODE); } return queue_length; }
static int createBinarySemaphore(key_t sem_key, int shm_id) { union semun sem_conf; int sem_id = semget(sem_key, NUM_OF_SEMAPHORES, IPC_CREAT|ALLOW_READ_WRITE_TO_ALL); if(sem_id < 0) { deleteFifo(); deleteSharedMemory(shm_id); // No checking needed, exits with error code. write(STDERR_FILENO, SEMGET_ERROR, sizeof(SEMGET_ERROR)); exit(EXIT_ERROR_CODE); } sem_conf.val = SEM_INIT; if(semctl(sem_id, 0, SETVAL, sem_conf) < 0) { deleteFifo(); deleteResources(shm_id, sem_id); // No checking needed, exits with error code. write(STDERR_FILENO, SEMCTL_ERROR, sizeof(SEMCTL_ERROR)); exit(EXIT_ERROR_CODE); } return sem_id; }
char *createSharedMemory(key_t key, int *shm_id) { char *p_shm_data = NULL; // Create shared memory *shm_id = shmget(key, SHM_SIZE_IN_BYTES, IPC_CREAT|ALLOW_READ_WRITE_TO_ALL); if(*shm_id < 0) { deleteFifo(); // No checking needed, exits with error code. write(STDERR_FILENO, SHMGET_ERROR, sizeof(SHMGET_ERROR)); exit(EXIT_ERROR_CODE); } // Connect to the shared memory. p_shm_data = (char *)shmat(*shm_id, 0, 0); if(SHMAT_FAILED == p_shm_data) { deleteFifo(); deleteSharedMemory(*shm_id); // No checking needed, exits with error code. write(STDERR_FILENO, SHMAT_ERROR, sizeof(SHMAT_ERROR)); exit(EXIT_ERROR_CODE); } return p_shm_data; }
int devClose(myDev * dev) { fifo * i = NULL; fifo * temp = NULL; if(dev==NULL) { errnoSet(NOT_OPEN); return -1; } //Prevent anyone from accessing this device while we're modifying it : if(semTake(dev->semMData,WAIT_FOREVER)==-1) { errnoSet(SEM_ERR); return -1; } if (dev->openned == 0) { errnoSet(NOT_OPEN); return -1; } else { //Find fifo corresponding to this task in drv->listFifo and deallocate it if (dev->firstFifo->taskId==taskIdSelf()) { temp=dev->firstFifo; dev->firstFifo=temp->nextFifo; deleteFifo(temp); free(temp); } else { for (i=dev->firstFifo;i->nextFifo->taskId==taskIdSelf();i=i->nextFifo); temp=i->nextFifo; i->nextFifo=temp->nextFifo; deleteFifo(temp); free(temp); } dev->openned--; } semGive(dev->semMData); return 0; }
static void writePidToFifo(void) { pid_t my_pid = 0; int fifo_fd = 0; // Get self PID. my_pid = getpid(); // Open FIFO. fifo_fd = open(FIFO_NAME, O_WRONLY); if(fifo_fd < 0) { deleteFifo(); // No checking needed, exits with error code. write(STDERR_FILENO, OPEN_ERROR, sizeof(OPEN_ERROR)); exit(EXIT_ERROR_CODE); } // Write process PID to FIFO. if(write(fifo_fd, (void*)&my_pid, sizeof(my_pid)) != sizeof(my_pid)) { deleteFifo(); // No checking needed, exits with error code. write(STDERR_FILENO, WRITE_ERROR, sizeof(WRITE_ERROR)); exit(EXIT_ERROR_CODE); } // Close FIFO. if(close(fifo_fd) < 0) { deleteFifo(); // No checking needed, exits with error code. write(STDERR_FILENO, CLOSE_ERROR, sizeof(CLOSE_ERROR)); exit(EXIT_ERROR_CODE); } }
int main(int argc, char *argv[]) { const unsigned int EXPECTED_ARGC = 2; const unsigned int KEY_FILE_ARG_INDEX = 1; const unsigned char KEY_CHAR = 'H'; const char ENDLINE[] = "\n"; const char SEPERATOR[] = ","; key_t key = 0; char *shm_addr = NULL; int csv_fd = 0, queue_length = 0, shm_id = 0, sem_id = 0; int job_number = 0, rel_prio = 0, real_prio = 0; initSigactions(); // Initialize the rand() seed. srand(time(NULL)); if(argc != EXPECTED_ARGC) { // No checking needed, exits with error code. write(STDERR_FILENO, NOF_INPUTS_ERROR, sizeof(NOF_INPUTS_ERROR)); exit(EXIT_ERROR_CODE); } // Create fifo. if(mkfifo(FIFO_NAME, ALLOW_READ_WRITE_TO_ALL) < 0) { // No checking needed, exits with error code. write(STDERR_FILENO, MKFIFO_ERROR, sizeof(MKFIFO_ERROR)); exit(EXIT_ERROR_CODE); } writePidToFifo(); // Wait for the queue process' singal. waitForSignal(); printf("got signal from %d!\n", Queue_Pid); // Generate key from the given file key = ftok(argv[KEY_FILE_ARG_INDEX], KEY_CHAR); if(key < 0) { deleteFifo(); // No checking needed, exits with error code. write(STDERR_FILENO, FTOK_ERROR, sizeof(FTOK_ERROR)); exit(EXIT_ERROR_CODE); } // Create shared memory. shm_addr = createSharedMemory(key, &shm_id); // Create semaphore. sem_id = createBinarySemaphore(key, shm_id); // Notify the queue.out process. if(kill(Queue_Pid, SIGUSR1) < 0) { deleteFifo(); // No checking needed, exits with error code. write(STDERR_FILENO, KILL_ERROR, sizeof(KILL_ERROR) - 1); exit(EXIT_ERROR_CODE); } queue_length = readQueueLengthFromFifo(); printf("Got N: %d\n", queue_length); // Done using the fifo - delete it. deleteFifo(); // Game Started! handleGame(shm_id, shm_addr, sem_id, queue_length, &job_number, \ &rel_prio, &real_prio); deleteResources(shm_id, sem_id); // Write results csv_fd = open(CSV_FILE_PATH, O_CREAT | O_APPEND | O_RDWR, ALLOW_READ_WRITE_TO_ALL); if(csv_fd < 0) { // No checking needed, exits with error code. write(STDERR_FILENO, OPEN_ERROR, sizeof(OPEN_ERROR) - 1); exit(EXIT_ERROR_CODE); } writeIntWithEnding(csv_fd, queue_length, SEPERATOR); writeIntWithEnding(csv_fd, job_number, SEPERATOR); writeIntWithEnding(csv_fd, rel_prio, SEPERATOR); writeIntWithEnding(csv_fd, real_prio, ENDLINE); return EXIT_OK_CODE; }