Programmation Avancée en C


pipe_cat_sig.c

00001 #include <sys/types.h>
00002 #include <sys/wait.h>
00003 #include <signal.h>
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <unistd.h>
00007 
00008 sig_atomic_t tubekaput = 0;
00009 
00010 static void traiteSIGPIPE(int n) {
00011         tubekaput = 1;
00012 }
00013 
00014 void ecrireverif(int desc, char c, char *prog) {
00015         write(desc, &c, 1);
00016         if (tubekaput) {
00017                 close(desc);
00018                 wait(NULL); /* pour ne pas avoir de zombie */
00019                 execlp(prog, prog, &c, NULL);
00020                 exit(EXIT_FAILURE);
00021         }
00022 }
00023 
00024 int main(int argc, char *argv[])
00025 {
00026         char c;
00027         int descfich[2];
00028 
00029         sigset_t mask;
00030         struct sigaction gestionnaire;
00031         gestionnaire.sa_handler = traiteSIGPIPE;
00032         gestionnaire.sa_flags = 0;
00033         if (sigemptyset(&mask))                         return EXIT_FAILURE;
00034         if (sigaction(SIGPIPE, &gestionnaire, NULL))    return EXIT_FAILURE;
00035         if (pipe(descfich))                             return EXIT_FAILURE;
00036 
00037         switch (fork()) {
00038         case -1:
00039                 return EXIT_FAILURE;
00040         case 0: /* fils */
00041                 close(descfich[1]);
00042                 while(read(descfich[0], &c, 1) == 1) {
00043                         putchar(c);
00044                 }
00045                 return 0;
00046         default: /* père */
00047                 close(descfich[0]);
00048                 if (argc == 2) /* il y a un caractère que l'on n'a pas écrit...*/
00049                         ecrireverif(descfich[1], argv[1][0], argv[0]);
00050                 while (read(STDIN_FILENO, &c, 1) == 1) {
00051                         ecrireverif(descfich[1], c, argv[0]);
00052                 }
00053                 return 0;
00054         }
00055 }