Advertisement
Guest User

alpha-usage

a guest
Jan 26th, 2020
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.23 KB | None | 0 0
  1. /*
  2.  * IPC:      Coda di messaggi, mappatura in memoria.
  3.  * PADRE:    creazione due processi figlio, stampa conteggio totale.
  4.  * SCANNER:  analisi ricorsiva dei file regolari nella directory indicata,
  5.              visualizza e poi invia ogni path completo come singolo messaggio.
  6.  * ANALYZER: conteggia i caratteri alfabetici contenuti nel file ricevuto,
  7.              visualizza un messaggio informativo e invia totale al parent.
  8.  * PADRE:   stampa a video il totale di caratteri alfabetici accumulato.
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <string.h>
  15. #include <fcntl.h>
  16. #include <dirent.h>
  17. #include <sys/mman.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include <sys/ipc.h>
  21. #include <sys/msg.h>
  22. #include <sys/wait.h>
  23. #define CURRENT "."
  24. #define SIZE 2048
  25. #define MSGSIZE sizeof(msg)-sizeof(long)
  26. #define PARENT 1
  27. #define ANALYZER 2
  28.  
  29. typedef struct{
  30.     long type; //destinatario del messaggio
  31.     char path[SIZE]; //path esplicito del file da leggere
  32.     unsigned int total; //caratteri alfabetici presenti in un file
  33. }msg;
  34.  
  35. /* stampa a video informazioni sul path corrente. */
  36. void printPath(char *mittente, char *path, char endchar){
  37.     fprintf(stdout, "%s> PATH: \"%s\"%c", mittente, path, endchar);
  38.  
  39. }
  40.  
  41. /* effettua l'analisi ricorsiva della directory indicata alla ricerca di file regolari.
  42. Per ogni file regolare e leggibile trovato verrà visualizzato un messaggio a video e
  43. verrà inviato un messaggio con il path di tale file regolare al processo Analyzer;
  44. */
  45. void scanner(int coda, char *path){
  46.     DIR *dir;
  47.     struct dirent *dp;
  48.     struct stat statfile;
  49.     char pathname[SIZE] = "";
  50.     msg messaggio;
  51.     messaggio.type = ANALYZER;
  52.     /* selezione del percorso passato come parametro */
  53.     if(chdir(path) == -1){
  54.         perror("chdir");
  55.         exit(1);
  56.     }
  57.     /* apertura della cartella passata come parametro */
  58.     if((dir = opendir(CURRENT))==NULL){
  59.         perror("opendir");
  60.         exit(1);
  61.     }
  62.     strcpy(messaggio.path, "");
  63.     //non analizza le sottocartelle
  64.     while((dp=readdir(dir))){
  65.         if( ((stat(dp->d_name, &statfile)) != -1) && S_ISREG(statfile.st_mode) ){
  66.             /*creazione del path completo tramite concatenazione*/
  67.             strcat(pathname, path);
  68.             strcat(pathname, "/");
  69.             strcat(pathname, dp->d_name);
  70.             printPath(" Scanner", pathname, '\n');
  71.             strcpy(messaggio.path, pathname);
  72.             strcpy(pathname, "");
  73.             messaggio.type = ANALYZER;
  74.             msgsnd(coda, &messaggio, MSGSIZE,0);
  75.         }
  76.     }
  77.     strcpy(messaggio.path, ""); //indica la fine della lettura
  78.     msgsnd(coda, &messaggio, MSGSIZE,0);   
  79.     /* chiusura della cartella */
  80.     closedir(dir);
  81.     exit(0);
  82. }
  83. /* Per ogni messaggio ricevuto contenente il path per un file regolare,
  84.    effettuerà il conteggio richiesto utilizzando la mappatura dei file in memoria,
  85.    visualizzerà un messaggio a video ed invierà un messaggio contenente il totale
  86. */
  87. void analyzer(int coda){
  88.     msg messaggio;
  89.     char * mapped;
  90.     struct stat statfile;
  91.     int fd;
  92.     int counter = 0;
  93.     //fprintf(stdout, "Analyzer> Analyzer avviato.\n");
  94.     while(1){
  95.         msgrcv(coda, &messaggio, MSGSIZE, ANALYZER,0);
  96.         if((strcmp(messaggio.path, "")==0))
  97.             break;
  98.         /*mappatura del file*/
  99.         if((fd = open(messaggio.path, O_RDONLY))==-1){
  100.             perror("open");
  101.             exit(1);
  102.         }
  103.         if(stat(messaggio.path, &statfile)==-1){
  104.             perror("stat");
  105.             exit(1);
  106.         }
  107.         if((mapped = mmap(NULL, statfile.st_size, PROT_READ, MAP_SHARED, fd, 0))==MAP_FAILED){
  108.             perror("mmap");
  109.             exit(1);
  110.         }
  111.         counter = 0;
  112.         for(int i = 0; mapped[i]!=EOF; i++){
  113.             if((mapped[i]>='a' && mapped[i]<='z') || (mapped[i]>='A' && mapped[i]<='Z'))
  114.                 counter++;
  115.         }
  116.         printPath("Analyzer", messaggio.path, '\0');
  117.         fprintf(stdout, "<%d lettere >\n", counter);
  118.         messaggio.total = counter;
  119.         messaggio.type = PARENT;
  120.         msgsnd(coda, &messaggio, MSGSIZE, 0);
  121.         munmap(mapped, statfile.st_size);
  122.         close(fd);
  123.     }
  124.     messaggio.total = -1; //indica la fine della lettura
  125.     messaggio.type = PARENT;
  126.     msgsnd(coda, &messaggio, MSGSIZE, 0);
  127.     exit(0);
  128. }
  129. int main(int argc, char **argv){
  130.     /* dichiarazione delle variabili */
  131.     char folderpath[SIZE]= "";
  132.     struct stat folderstat = {0};
  133.     int qid;
  134.     msg messaggio;
  135.     int totaleconteggio = 0;
  136.     /*controllo sui parametri*/
  137.     if(argc == 1){
  138.         //set folderpath to current
  139.         strcpy(folderpath, CURRENT);
  140.         printf("   Padre> Nessun argomento. Impostazioni di default.\n");
  141.         printPath("   Padre", folderpath, '\n');
  142.     }else{
  143.         strcpy(folderpath, argv[1]);
  144.         stat(folderpath, &folderstat);
  145.         if ( (argc == 2) && ( S_ISDIR(folderstat.st_mode) ) ){
  146.             printPath("   Padre",folderpath, '\n');
  147.         }else{
  148.             fprintf(stderr, "  Padre> Parametri non conformi. Uscita dal programma.\n");
  149.             fprintf(stderr, "  Padre> Utilizzo: %s   [url-directory]\n", argv[0]);
  150.             exit(1);
  151.         }
  152.     }
  153.     /* creazione della coda di messaggi */
  154.     if( (qid = msgget(IPC_PRIVATE, IPC_CREAT|0660) ) ==-1){
  155.         perror("msgget");
  156.         exit(1);
  157.     }
  158.     /* creazione dei figli*/
  159.     if (fork()==0) scanner(qid, folderpath);
  160.     if (fork()==0) analyzer(qid);
  161.     while(1){
  162.         msgrcv(qid, &messaggio, MSGSIZE, PARENT, 0);
  163.         if (messaggio.total ==-1)
  164.             break;
  165.         totaleconteggio += messaggio.total;
  166.     }
  167.     fprintf(stdout, "   Padre>  END: %d caratteri alfabetici letti in totale.\n", totaleconteggio);
  168.     wait(NULL);
  169.     wait(NULL);
  170.     /* chiusura delle strutture dati */
  171.     msgctl(qid, IPC_RMID, NULL);
  172.  
  173. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement