Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * IPC: Coda di messaggi, mappatura in memoria.
- * PADRE: creazione due processi figlio, stampa conteggio totale.
- * SCANNER: analisi ricorsiva dei file regolari nella directory indicata,
- visualizza e poi invia ogni path completo come singolo messaggio.
- * ANALYZER: conteggia i caratteri alfabetici contenuti nel file ricevuto,
- visualizza un messaggio informativo e invia totale al parent.
- * PADRE: stampa a video il totale di caratteri alfabetici accumulato.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <fcntl.h>
- #include <dirent.h>
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <sys/wait.h>
- #define CURRENT "."
- #define SIZE 2048
- #define MSGSIZE sizeof(msg)-sizeof(long)
- #define PARENT 1
- #define ANALYZER 2
- typedef struct{
- long type; //destinatario del messaggio
- char path[SIZE]; //path esplicito del file da leggere
- unsigned int total; //caratteri alfabetici presenti in un file
- }msg;
- /* stampa a video informazioni sul path corrente. */
- void printPath(char *mittente, char *path, char endchar){
- fprintf(stdout, "%s> PATH: \"%s\"%c", mittente, path, endchar);
- }
- /* effettua l'analisi ricorsiva della directory indicata alla ricerca di file regolari.
- Per ogni file regolare e leggibile trovato verrà visualizzato un messaggio a video e
- verrà inviato un messaggio con il path di tale file regolare al processo Analyzer;
- */
- void scanner(int coda, char *path){
- DIR *dir;
- struct dirent *dp;
- struct stat statfile;
- char pathname[SIZE] = "";
- msg messaggio;
- messaggio.type = ANALYZER;
- /* selezione del percorso passato come parametro */
- if(chdir(path) == -1){
- perror("chdir");
- exit(1);
- }
- /* apertura della cartella passata come parametro */
- if((dir = opendir(CURRENT))==NULL){
- perror("opendir");
- exit(1);
- }
- strcpy(messaggio.path, "");
- //non analizza le sottocartelle
- while((dp=readdir(dir))){
- if( ((stat(dp->d_name, &statfile)) != -1) && S_ISREG(statfile.st_mode) ){
- /*creazione del path completo tramite concatenazione*/
- strcat(pathname, path);
- strcat(pathname, "/");
- strcat(pathname, dp->d_name);
- printPath(" Scanner", pathname, '\n');
- strcpy(messaggio.path, pathname);
- strcpy(pathname, "");
- messaggio.type = ANALYZER;
- msgsnd(coda, &messaggio, MSGSIZE,0);
- }
- }
- strcpy(messaggio.path, ""); //indica la fine della lettura
- msgsnd(coda, &messaggio, MSGSIZE,0);
- /* chiusura della cartella */
- closedir(dir);
- exit(0);
- }
- /* Per ogni messaggio ricevuto contenente il path per un file regolare,
- effettuerà il conteggio richiesto utilizzando la mappatura dei file in memoria,
- visualizzerà un messaggio a video ed invierà un messaggio contenente il totale
- */
- void analyzer(int coda){
- msg messaggio;
- char * mapped;
- struct stat statfile;
- int fd;
- int counter = 0;
- //fprintf(stdout, "Analyzer> Analyzer avviato.\n");
- while(1){
- msgrcv(coda, &messaggio, MSGSIZE, ANALYZER,0);
- if((strcmp(messaggio.path, "")==0))
- break;
- /*mappatura del file*/
- if((fd = open(messaggio.path, O_RDONLY))==-1){
- perror("open");
- exit(1);
- }
- if(stat(messaggio.path, &statfile)==-1){
- perror("stat");
- exit(1);
- }
- if((mapped = mmap(NULL, statfile.st_size, PROT_READ, MAP_SHARED, fd, 0))==MAP_FAILED){
- perror("mmap");
- exit(1);
- }
- counter = 0;
- for(int i = 0; mapped[i]!=EOF; i++){
- if((mapped[i]>='a' && mapped[i]<='z') || (mapped[i]>='A' && mapped[i]<='Z'))
- counter++;
- }
- printPath("Analyzer", messaggio.path, '\0');
- fprintf(stdout, "<%d lettere >\n", counter);
- messaggio.total = counter;
- messaggio.type = PARENT;
- msgsnd(coda, &messaggio, MSGSIZE, 0);
- munmap(mapped, statfile.st_size);
- close(fd);
- }
- messaggio.total = -1; //indica la fine della lettura
- messaggio.type = PARENT;
- msgsnd(coda, &messaggio, MSGSIZE, 0);
- exit(0);
- }
- int main(int argc, char **argv){
- /* dichiarazione delle variabili */
- char folderpath[SIZE]= "";
- struct stat folderstat = {0};
- int qid;
- msg messaggio;
- int totaleconteggio = 0;
- /*controllo sui parametri*/
- if(argc == 1){
- //set folderpath to current
- strcpy(folderpath, CURRENT);
- printf(" Padre> Nessun argomento. Impostazioni di default.\n");
- printPath(" Padre", folderpath, '\n');
- }else{
- strcpy(folderpath, argv[1]);
- stat(folderpath, &folderstat);
- if ( (argc == 2) && ( S_ISDIR(folderstat.st_mode) ) ){
- printPath(" Padre",folderpath, '\n');
- }else{
- fprintf(stderr, " Padre> Parametri non conformi. Uscita dal programma.\n");
- fprintf(stderr, " Padre> Utilizzo: %s [url-directory]\n", argv[0]);
- exit(1);
- }
- }
- /* creazione della coda di messaggi */
- if( (qid = msgget(IPC_PRIVATE, IPC_CREAT|0660) ) ==-1){
- perror("msgget");
- exit(1);
- }
- /* creazione dei figli*/
- if (fork()==0) scanner(qid, folderpath);
- if (fork()==0) analyzer(qid);
- while(1){
- msgrcv(qid, &messaggio, MSGSIZE, PARENT, 0);
- if (messaggio.total ==-1)
- break;
- totaleconteggio += messaggio.total;
- }
- fprintf(stdout, " Padre> END: %d caratteri alfabetici letti in totale.\n", totaleconteggio);
- wait(NULL);
- wait(NULL);
- /* chiusura delle strutture dati */
- msgctl(qid, IPC_RMID, NULL);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement