diff --git a/SCR3.1/TP5/Exo1/a.out b/SCR3.1/TP5/Exo1/a.out new file mode 100755 index 0000000..ac8f247 Binary files /dev/null and b/SCR3.1/TP5/Exo1/a.out differ diff --git a/SCR3.1/TP5/Exo1/pipe-ex.c b/SCR3.1/TP5/Exo1/pipe-ex.c new file mode 100644 index 0000000..6ab1aa6 --- /dev/null +++ b/SCR3.1/TP5/Exo1/pipe-ex.c @@ -0,0 +1,183 @@ +#include +#include +#include +#include +#include +#include + +#define READ_END 0 +#define WRITE_END 1 + +// Fonction pour la gestion des erreurs +void error_exit(const char *msg) { + perror(msg); + exit(EXIT_FAILURE); +} + +// Fonction du processus Pf2 (Écriture) +void process_pf2(int pipefd[2]) { + // Pf2 n'a besoin que de l'extrémité d'écriture du tube + if (close(pipefd[READ_END]) == -1) { + error_exit("Pf2: close(READ_END)"); + } + + printf("Pf2 (PID: %d) démarré. Écrit toutes les 3 secondes.\n", getpid()); + + pid_t pid_to_write; + + while (1) { + pid_to_write = getpid(); + ssize_t bytes_written = write(pipefd[WRITE_END], &pid_to_write, sizeof(pid_t)); + + if (bytes_written == -1) { + if (errno == EPIPE) { + // Le tube a été fermé par le lecteur (Pf1f1) + fprintf(stderr, "Pf2 (PID: %d): Erreur: Pipe fermé. Arrêt de l'écriture.\n", getpid()); + break; + } + error_exit("Pf2: write"); + } + + printf("Pf2 (PID: %d) écrit: %d (taille: %zd octets)\n", getpid(), pid_to_write, bytes_written); + + // Attendre 3 secondes + sleep(3); + } + + // Fermer l'extrémité d'écriture avant de terminer + if (close(pipefd[WRITE_END]) == -1) { + error_exit("Pf2: close(WRITE_END) final"); + } + exit(EXIT_SUCCESS); +} + +// Fonction du processus Pf1f1 (Lecture) +void process_pf1f1(int pipefd[2]) { + // Pf1f1 n'a besoin que de l'extrémité de lecture du tube + if (close(pipefd[WRITE_END]) == -1) { + error_exit("Pf1f1: close(WRITE_END)"); + } + + printf("Pf1f1 (PID: %d) démarré. Lit toutes les 1 seconde.\n", getpid()); + + pid_t received_pid; + ssize_t bytes_read; + + while (1) { + bytes_read = read(pipefd[READ_END], &received_pid, sizeof(pid_t)); + + if (bytes_read == -1) { + error_exit("Pf1f1: read"); + } else if (bytes_read == 0) { + // Fin de fichier (l'écrivain Pf2 a fermé son extrémité) + printf("Pf1f1 (PID: %d): Fin du tube détectée. Arrêt de la lecture.\n", getpid()); + break; + } else if (bytes_read != sizeof(pid_t)) { + // Lecture partielle inattendue + fprintf(stderr, "Pf1f1 (PID: %d): Avertissement: Lecture partielle (%zd octets au lieu de %zu)\n", + getpid(), bytes_read, sizeof(pid_t)); + } else { + // Lecture réussie + printf("Pf1f1 (PID: %d) lit: %d (taille: %zd octets)\n", getpid(), received_pid, bytes_read); + } + + // Attendre 1 seconde + sleep(1); + } + + // Fermer l'extrémité de lecture avant de terminer + if (close(pipefd[READ_END]) == -1) { + error_exit("Pf1f1: close(READ_END) final"); + } + exit(EXIT_SUCCESS); +} + +int main(void) { + int pipefd[2]; + pid_t pid_pf2, pid_pf1, pid_pf1f1; + + printf("Processus P (PID: %d) démarré.\n", getpid()); + + // 1. Créer le tube entre Pf2 et Pf1f1 + if (pipe(pipefd) == -1) { + error_exit("pipe"); + } + printf("Tube créé: descripteur de lecture=%d, descripteur d'écriture=%d\n", + pipefd[READ_END], pipefd[WRITE_END]); + + // 2. Créer Pf2 + pid_pf2 = fork(); + if (pid_pf2 == -1) { + error_exit("fork Pf2"); + } + + if (pid_pf2 == 0) { + // Code de Pf2 + process_pf2(pipefd); + } + + // Processus P (continue) + // 3. Créer Pf1 + pid_pf1 = fork(); + if (pid_pf1 == -1) { + error_exit("fork Pf1"); + } + + if (pid_pf1 == 0) { + // Code de Pf1 + printf("Pf1 (PID: %d) démarré. Création de Pf1f1.\n", getpid()); + + // 4. Créer Pf1f1 (fils de Pf1) + pid_pf1f1 = fork(); + if (pid_pf1f1 == -1) { + error_exit("fork Pf1f1"); + } + + if (pid_pf1f1 == 0) { + // Code de Pf1f1 + process_pf1f1(pipefd); + } else { + // Pf1 attend la terminaison de Pf1f1 + printf("Pf1 (PID: %d) attend Pf1f1 (PID: %d).\n", getpid(), pid_pf1f1); + + // Pf1 ne lit ni n'écrit dans le tube, donc il doit fermer les deux descripteurs hérités + if (close(pipefd[READ_END]) == -1) { + error_exit("Pf1: close(READ_END)"); + } + if (close(pipefd[WRITE_END]) == -1) { + error_exit("Pf1: close(WRITE_END)"); + } + + if (waitpid(pid_pf1f1, NULL, 0) == -1) { + error_exit("waitpid Pf1f1"); + } + printf("Pf1 (PID: %d): Pf1f1 terminé.\n", getpid()); + exit(EXIT_SUCCESS); + } + } + + // Processus P (attente des enfants) + printf("P (PID: %d) attend Pf2 (PID: %d) et Pf1 (PID: %d).\n", getpid(), pid_pf2, pid_pf1); + + // Le processus P ne communique pas via le tube, il doit donc fermer les descripteurs hérités + if (close(pipefd[READ_END]) == -1) { + error_exit("P: close(READ_END)"); + } + if (close(pipefd[WRITE_END]) == -1) { + error_exit("P: close(WRITE_END)"); + } + + // Attendre la terminaison des deux processus enfants directs (Pf2 et Pf1) + if (waitpid(pid_pf2, NULL, 0) == -1) { + error_exit("waitpid Pf2"); + } + printf("P (PID: %d): Pf2 terminé.\n", getpid()); + + if (waitpid(pid_pf1, NULL, 0) == -1) { + error_exit("waitpid Pf1"); + } + printf("P (PID: %d): Pf1 terminé.\n", getpid()); + + printf("P (PID: %d): Tous les processus enfants sont terminés. Sortie.\n", getpid()); + return 0; +}