Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*****************************************************************
- SPECIFICATION TO BE IMPLEMENTED:
- Implementare un programma che riceva in input tramite argv[] i pathname
- associati ad N file, con N maggiore o uguale ad 1. Per ognuno di questi
- file generi un processo che legga tutte le stringhe contenute in quel file
- e le scriva in un'area di memoria condivisa con il processo padre. Si
- supponga per semplicita' che lo spazio necessario a memorizzare le stringhe
- di ognuno di tali file non ecceda 4KB.
- Il processo padre dovra' attendere che tutti i figli abbiano scritto in
- memoria il file a loro associato, e successivamente dovra' entrare in pausa
- indefinita.
- D'altro canto, ogni figlio dopo aver scritto il contenuto del file nell'area
- di memoria condivisa con il padre entrera' in pausa indefinita.
- L'applicazione dovra' gestire il segnale SIGINT (o CTRL_C_EVENT nel caso
- WinAPI) in modo tale che quando il processo padre venga colpito da esso dovra'
- stampare a terminale il contenuto corrente di tutte le aree di memoria
- condivisa anche se queste non sono state completamente popolate dai processi
- figli.
- *****************************************************************/
- #include <unistd.h>
- #include <errno.h>
- #include <signal.h>
- #include <pthread.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <sys/mman.h>
- #include <semaphore.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define PAGESIZE (4096)
- int N_FILES;
- int ds_sem;
- char **buffers;
- struct sembuf oper;
- void error_handler(char *message) {
- fprintf(stderr, "%s\n", message);
- perror("The error was: ");
- exit(EXIT_FAILURE);
- }
- void read_proc(char *path, int id) {
- FILE *file = fopen(path, "r");
- int ret;
- if (file == NULL)
- error_handler("Opening file failed");
- char *index = buffers[id];
- while (fscanf(file, "%s", index) != EOF) {
- printf("Reading from %s: %s ...\n", path, index);
- index += strlen(index) + 1;
- }
- //signal(S)
- oper.sem_num = 0;
- oper.sem_op = 1;
- oper.sem_flg = 0;
- while (semop(ds_sem, &oper, 1) == -1)
- if (errno != EINTR)
- error_handler("Semaphore operation failed");
- return;
- }
- void printer(int signo) {
- printf("\n\nReading from buffers ...\n");
- for (int i = 0; i < N_FILES; ++i) {
- printf("FILE %d\n", i + 1);
- char *temp = buffers[i];
- while (strcmp(temp, "\0") != 0) {
- printf("%s\n",temp);
- temp += strlen(temp) + 1;
- }
- }
- }
- int main(int argc, char **argv) {
- if (argc < 2) {
- fprintf(stderr, "\n\tusage: prog file_1 file_2 ... [file_N]\n\n");
- exit(EXIT_FAILURE);
- }
- int ret;
- N_FILES = argc - 1;
- sigset_t set;
- struct sigaction act;
- memset((void *) &act, 0, sizeof(struct sigaction));
- memset((void *) &oper, 0, sizeof(struct sembuf));
- ret = sigfillset(&set);
- if (ret == -1)
- error_handler("Signal initialization failed");
- act.sa_mask = set;
- act.sa_handler = printer;
- act.sa_flags = 0;
- ret = sigaction(SIGINT, &act, NULL);
- if (ret == -1)
- error_handler("Signal initialization failed");
- ds_sem = semget(IPC_PRIVATE, 1, IPC_CREAT | 0660);
- if (ds_sem == -1)
- error_handler("Semaphore initialization failed");
- ret = semctl(ds_sem, 0, SETVAL, 0);
- if (ret == -1)
- error_handler("Semaphore setup failed");
- buffers = (char **)malloc(N_FILES * sizeof(char *));
- if (buffers == NULL)
- error_handler("Malloc failed");
- for (int i = 0; i < N_FILES; ++i) {
- buffers[i] = mmap(NULL, PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
- if (buffers[i] == MAP_FAILED)
- error_handler("Memory map failed");
- }
- pid_t pids[N_FILES];
- for (int i = 0; i < N_FILES; ++i) {
- pids[i] = fork();
- if (pids[i] == -1)
- error_handler("Fork failed");
- if (pids[i] == 0) {
- signal(SIGINT, SIG_IGN);
- read_proc(argv[i + 1], i);
- while (1)
- pause();
- }
- }
- oper.sem_num = 0;
- oper.sem_op = - N_FILES;
- oper.sem_flg = 0;
- while (semop(ds_sem, &oper, 1) == -1)
- if (errno != EINTR)
- error_handler("Semaphore operation failed");
- while (1)
- pause();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement