Created
April 21, 2016 18:08
-
-
Save Danysan1/e7e06ff482404073c93a9e60e8b15fb9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <sys/wait.h> | |
int pipe1[2], pipe2[2]; | |
void errorExit(char * string) { | |
perror(string); | |
exit(EXIT_FAILURE); | |
} | |
pid_t creaP1(int * pipe1, int * pipe2, const char * const fileA, const char c) { | |
pid_t pid = fork(); | |
if (pid == 0) { | |
puts("P1 parte"); | |
close(pipe1[0]); | |
close(pipe2[1]); | |
// Apertura del file | |
int fdA = open(fileA, O_RDONLY); | |
if (fdA < 0) | |
errorExit("P1: Impossibile aprire il file di input"); | |
// Conto M | |
int m = 0; | |
char buf; | |
ssize_t letti; | |
while((letti = read(fdA, &buf, sizeof(char))) == sizeof(char)) { | |
if(buf == c) { | |
// Carattere trovato | |
m++; | |
// Scorro il resto della riga | |
while(((letti = read(fdA, &buf, sizeof(char))) == sizeof(char)) && (buf != '\n')) | |
; // Non fare nulla | |
} | |
} | |
// Invio il valore di M | |
printf("P1: M = %d\n", m); | |
write(pipe1[1], &m, sizeof(int)); | |
// Ricevo il valore di N | |
char n[10]; | |
read(pipe2[0], n, 10 * sizeof(char)); | |
int nInt = atoi(n); | |
// Invio il valore di N | |
printf("P1: N = %s = %d\n", n, nInt); | |
write(pipe1[1], &nInt, sizeof(int)); | |
// Chiusura pipe e file | |
if((close(pipe1[1]) == 0) && (close(pipe2[0]) == 0) && (close(fdA) == 0)) { | |
puts("P1 termina"); | |
exit(EXIT_SUCCESS); | |
} else { | |
errorExit("P1: errore nella chiusura dell'I/O"); | |
} | |
} else if (pid > 0) { | |
printf("P1 creato con PID %d\n", pid); | |
close(pipe1[1]); | |
close(pipe2[0]); | |
} else | |
errorExit("Errore nella fork di P1"); | |
return pid; | |
} | |
pid_t creaP2(int * pipe2, const char * fileB, const char c) { | |
pid_t pid = fork(); | |
if (pid == 0) { | |
puts("P2 parte"); | |
close(pipe1[0]); | |
// Preparo il carattere | |
char arg[2] = {c,'\0'}; | |
//Redirigo stdout in pipe2[1] | |
if(close(1) != 0) | |
errorExit("P2: chiusura di stdout fallita"); | |
int d = dup(pipe2[1]); | |
if (d != 1) | |
errorExit("P2: sostituzione di stdout fallita"); | |
//Lancio "grep -c <carattere> <file>" | |
puts("P2 lancia grep"); | |
execlp("grep", "grep", "-c", arg, fileB, NULL); | |
// Exec fallita | |
close(pipe2[1]); | |
errorExit("P2: Grep fallito"); | |
} else if (pid > 0) { | |
printf("P2 creato con PID %d\n", pid); | |
close(pipe2[1]); | |
} else | |
errorExit("Errore nella fork di P2"); | |
return pid; | |
} | |
int main (int argc, char ** argv) { | |
if (argc < 4) { | |
printf("Utilizzo: %s <file_A> <file_B> <carattere>\n", argv[0]); | |
errorExit("Argomenti insufficienti"); | |
} | |
// Controllo che il file da leggere esista e sia leggibile | |
if (access(argv[1], F_OK | R_OK) != 0) { | |
printf("Utilizzo: %s <file_A> <file_B> <carattere>\n", argv[0]); | |
errorExit("File B non leggibile"); | |
} | |
// Controllo che il file di destinazione non esista | |
if (access(argv[2], F_OK | R_OK) != 0) { | |
printf("Utilizzo: %s <file_A> <file_B> <carattere>\n", argv[0]); | |
errorExit("File B non leggibile"); | |
} | |
// Controllo che il carattere sia valido | |
if(strlen(argv[3]) != 1){ | |
printf("Utilizzo: %s <file_A> <file_B> <carattere>\n", argv[0]); | |
errorExit("Carattere non valido"); | |
} | |
// char c = argv[3][0] | |
int pipe1[2]; | |
if(pipe(pipe1) != 0) | |
errorExit("Errore nel creare la pipe P0-P1"); | |
int pipe2[2]; | |
if(pipe(pipe2) != 0) | |
errorExit("Errore nel creare la pipe P1-P2"); | |
creaP1(pipe1, pipe2, argv[1], argv[3][0]); | |
creaP2(pipe2, argv[2], argv[3][0]); | |
// Atesa dei figli | |
printf("P0 attende\n"); | |
int statusA, statusB; | |
pid_t pidA = wait(&statusA), pidB = wait(&statusB); | |
printf("P0 riparte\n"); | |
if (statusA != EXIT_SUCCESS || statusB != EXIT_SUCCESS) { | |
printf("Un figlio è terminato con un errore (%d: %d, %d: %d)\n", pidA, statusA, pidB, statusB); | |
exit(EXIT_FAILURE); | |
} | |
//Lettura risultati | |
int count; | |
if(read(pipe1[0], &count, sizeof(int)) == sizeof(int)) | |
printf("%s contiene %c in %d righe\n", argv[1], argv[3][0], count); | |
if(read(pipe1[0], &count, sizeof(int)) == sizeof(int)) | |
printf("%s contiene %c in %d righe\n", argv[2], argv[3][0], count); | |
return(EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment