Untitled
unknown
plain_text
a month ago
5.3 kB
4
Indexable
Never
/****************************************************************** Welcome to the Operating System examination You are editing the '/home/esame/prog.c' file. You cannot remove this file, just edit it so as to produce your own program according to the specification listed below. In the '/home/esame/'directory you can find a Makefile that you can use to compile this program to generate an executable named 'prog' in the same directory. Typing 'make posix' you will compile for Posix, while typing 'make winapi' you will compile for WinAPI just depending on the specific technology you selected to implement the given specification. Most of the required header files (for either Posix or WinAPI compilation) are already included in the head of the prog.c file you are editing. At the end of the examination, the last saved snapshot of this file will be automatically stored by the system and will be then considered for the evaluation of your exam. Modifications made to prog.c which are not saved by you via the editor will not appear in the stored version of the prog.c file. In other words, unsaved changes will not be tracked, so please save this file when you think you have finished software development. You can also modify the Makefile if requesed, since this file will also be automatically stored together with your program and will be part of the final data to be evaluated for your exam. PLEASE BE CAREFUL THAT THE LAST SAVED VERSION OF THE prog.c FILE (and of the Makfile) WILL BE AUTOMATICALLY STORED WHEN YOU CLOSE YOUR EXAMINATION VIA THE CLOSURE CODE YOU RECEIVED, OR WHEN THE TIME YOU HAVE BEEN GRANTED TO DEVELOP YOUR PROGRAM EXPIRES. SPECIFICATION TO BE IMPLEMENTED: Implementare una programma che riceva in input, tramite argv[], i nomi di N differenti file F1 ... FN, con N maggiore o uguale a 1, che dovranno essere creati o troncati se gia' esistenti. Per ognuno dei file dovra' essere attivato un nuovo processo che ne gestira' il contenuto (indichiamo quindi con P1 ... PN i processi che dovranno essere attivati). Ciascun processo Pi leggera' dallo standard input 5 caratteri per volta in modo atomico rispetto alle attivita' degli altri processi, e dovra' scriverli sul file che sta gestendo. Anche la scrittura dei 5 caratteri sul file destinazione deve risultare come un'azione atomica, ovvero i caratteri non possono essere scritti sui file individualmente. L'applicazione dovra' gestire il segnale SIGINT (o CTRL_C_EVENT nel caso WinAPI) in modo tale che quando il processo originale venga colpito esso dovra' riportare su standard output i 5 ultimi caratteri correntemente presenti su ciascuno degli N file gestiti. Tutti gli altri processi non dovranno eseguire alcuna attivita' in caso di arrivo di segnalazione. In caso non vi sia immissione di dati sullo standard input, e non vi siano segnalazioni, l'applicazione dovra' utilizzare non piu' del 5% della capacita' di lavoro della CPU. *****************************************************************/ #ifdef Posix_compile #include <unistd.h> #include <errno.h> #include <signal.h> #include <pthread.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/mman.h> #include <sys/sem.h> #include <semaphore.h> #include <fcntl.h> #else #include <windows.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> int N; char** file_names; int pid; int parent_pid; void func_child(int fd); int sem_id; //id del semaforo accessibile a tutti i figli int* array_fd; void func_signal(); int main(int argc, char** argv) { N = argc-1; if(N == 0) { printf("errore argomenti\n"); exit(-1); } file_names = malloc(sizeof(char*)*N); for(size_t i=0; i<N; i++){ file_names[i] = argv[i+1]; } sem_id = semget(IPC_PRIVATE, 1, IPC_CREAT|0664); if(sem_id == -1) { printf("errore creazione semaforo\n"); exit(-1); } int semctl_return = semctl(sem_id, 0, SETVAL, 1); //0 è il numero di semaforo, che e' solo uno. SETVAL indica quale operazione voglio fare: imposta il token. // 1 è il token che imposto all'inizio. if(semctl_return == -1) { printf("errore impostazione semaforo\n"); exit(-1); } array_fd = malloc(sizeof(int)*N); for(size_t i=0; i<N; i++) { array_fd[i] = creat(file_names[i], 0664); pid = fork(); if(pid == -1) { printf("errore creazione processo\n"); exit(-1); }else if(pid == 0) { func_child(array_fd[i]); }else{ parent_pid = getpid(); signal(SIGINT, func_signal); } } } void func_child(int fd){ char buffer[6]; struct sembuf so; while(1){ so.sem_num = 0; //wait so.sem_op = -1; so.sem_flg = 0; int semop_check = semop(sem_id, &so, 1); //ho una sola operazione if(semop_check == -1) { printf("errore operazione semaforo\n"); exit(-1); } read(STDIN_FILENO, buffer, 5); write(fd, buffer, 5); so.sem_num = 0; //signal so.sem_op = 1; so.sem_flg = 0; semop_check = semop(sem_id, &so, 1); if(semop_check == -1) { printf("errore operazione semaforo\n"); exit(-1); } } } void func_signal() { char buffer[6]; for(size_t i=0; i<N; i++){ read(array_fd[i], buffer, 5); write(STDOUT_FILENO, buffer, 5); } }
Leave a Comment