Skip to content

Instantly share code, notes, and snippets.

@Danysan1
Created April 21, 2016 18:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Danysan1/e7e06ff482404073c93a9e60e8b15fb9 to your computer and use it in GitHub Desktop.
Save Danysan1/e7e06ff482404073c93a9e60e8b15fb9 to your computer and use it in GitHub Desktop.
#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