Warning: Undefined array key "view" in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 2

Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 47

Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 48

Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 49

Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 50

Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php:2) in /var/www/html/wp-content/uploads/classes/so/lab-exams/index.php on line 51
/* Sistemi Operativi - prova di laboratorio * compito del 13/07/2016 - soluzione */ /* serve per utilizzare la funzione non-POSIX strcasestr() */ #define _GNU_SOURCE 1 #include #include #include #include #include #include #define FIFO_PATHNAME_TEMPLATE "/tmp/my_fgrep_%d.fifo" #define MAX_LEN_BUFFER 2048 void reader(const char *input, int pipe_fd) { FILE *input_fs, *output_fs; char buffer[MAX_LEN_BUFFER]; if (input == NULL) input_fs = stdin; else if ((input_fs = fopen(input, "r")) == NULL) { perror(input); exit(1); } if ((output_fs = fdopen(pipe_fd, "w")) == NULL) { perror("pipe"); exit(1); } while (fgets(buffer, MAX_LEN_BUFFER, input_fs) != NULL) fputs(buffer, output_fs); exit(0); } void filterer(int pipe_fd, const char *output_fifo, const char *word, char case_insensitive, char inverse_logic) { FILE *input_fs, *output_fs; char buffer[MAX_LEN_BUFFER]; if ((input_fs = fdopen(pipe_fd, "r")) == NULL) { perror("pipe"); exit(1); } if ((output_fs = fopen(output_fifo, "w")) == NULL) { perror(output_fifo); exit(1); } while (fgets(buffer, MAX_LEN_BUFFER, input_fs) != NULL) { char match; if (case_insensitive) match = (strcasestr(buffer, word) != NULL); else match = (strstr(buffer, word) != NULL); if ((inverse_logic && !match) || (!inverse_logic && match)) fputs(buffer, output_fs); } exit(0); } void writer(const char *input_fifo) { FILE *input_fs; char buffer[MAX_LEN_BUFFER]; if ((input_fs = fopen(input_fifo, "r")) == NULL) { perror(input_fifo); exit(1); } while (fgets(buffer, MAX_LEN_BUFFER, input_fs) != NULL) fputs(buffer, stdout); exit(0); } int main(int argc, char **argv) { char case_insensitive = 0; char inverse_logic = 0; char *word = NULL; char *input = NULL; struct stat sb; int pipe_fds[2]; char fifo_pathname[MAX_LEN_BUFFER]; /* analizza la command-line */ for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-i") == 0) { case_insensitive = 1; } else if (strcmp(argv[i], "-v") == 0) { inverse_logic = 1; } else if (strlen(argv[i]) > 0) { if (word == NULL) { word = argv[i]; } else { if ((stat(argv[i], &sb) == 0) && (S_ISREG(sb.st_mode))) input = argv[i]; else { perror(argv[i]); exit(1); } } } } if (word == NULL) { printf("use: my-fgrep [-i] [-v] [file]\n"); exit(1); } if (pipe(pipe_fds) == -1) { perror("pipe"); exit(1); } /* utilizza nel nome della FIFO sul file-system il PID del * processo padre: questo permette di usare FIFO diverse per * istanze multiple del programma; usando la stessa fifo l'ultimo * esempio nel testo del compito non funzionerebbe... */ snprintf(fifo_pathname, MAX_LEN_BUFFER, FIFO_PATHNAME_TEMPLATE, getpid()); /* controllo se la FIFO sul file-system esiste gia', * eventualmente la crea */ if (stat(fifo_pathname, &sb) == -1) { if (!S_ISFIFO(sb.st_mode)) unlink(fifo_pathname); if (mkfifo(fifo_pathname, 0600) == -1) { perror(fifo_pathname); exit(1); } } if (fork() == 0) { /* chiude il canale di input sulla pipe nel figlio reader */ close(pipe_fds[0]); reader(input, pipe_fds[1]); } if (fork() == 0) { /* chiude il canale di output sulla pipe nel figlio filterer */ close(pipe_fds[1]); filterer(pipe_fds[0], fifo_pathname, word, case_insensitive, inverse_logic); } /* chiude entrambi i canali sulla pipe: non servono ne' al figlio * writer, ne' al padre; mantenerli aperti non permetterebbe la notifica * dell'EOF al figlio filterer */ close(pipe_fds[0]); close(pipe_fds[1]); if (fork() == 0) writer(fifo_pathname); wait(NULL); wait(NULL); wait(NULL); if (unlink(fifo_pathname) == -1) { perror(fifo_pathname); exit(1); } exit(0); }