TA043

Sistemas Operativos (TA043)
Index Commits Files Refs
pract/process_unidir_pipe.c (2792B)
   1 /*
   2  * Process Unidirectional Pipe
   3  * Martin Klöckner - mklockner@fi.uba.ar
   4  *
   5  * Based on example given in wait(2) man page
   6  */
   7 
   8 #include <stdio.h>
   9 #include <stdlib.h>
  10 #include <string.h>
  11 #include <unistd.h>
  12 #include <sys/wait.h>
  13 #include <stdint.h>
  14 
  15 #define LOG_ENABLE     true
  16 #define PIPE_READ_END  0
  17 #define PIPE_WRITE_END 1
  18 
  19 #if true == LOG_ENABLE
  20 #define LOG(fmt, ...) do {                                      \
  21         printf("[LOG] "fmt, ##__VA_ARGS__); \
  22     } while (0)
  23 #define LOG_ID(fmt, ...) do {                                 \
  24         printf("[LOG][%ld] "fmt, proc_count, ##__VA_ARGS__); \
  25     } while (0)
  26 #else
  27 #define LOG(fmt, ...)
  28 #define PROC_LOG(fmt, ...)
  29 #endif
  30 
  31 int main (void)
  32 {
  33     int wstatus, cpid, proc_count;
  34     int pipefd[2];
  35     char buf;
  36 
  37     proc_count = 0;
  38 
  39     if (pipe(pipefd) == -1)
  40     {
  41         perror("pipe");
  42         exit(EXIT_FAILURE);
  43     }
  44 
  45     cpid = fork();
  46 
  47     if (cpid == -1)
  48     {
  49         perror("fork");
  50         exit(EXIT_FAILURE);
  51     }
  52     else if (cpid == 0)
  53     {
  54         // Child
  55 
  56         proc_count++;
  57         LOG_ID("PID is %jd\n", (intmax_t) getpid());
  58 
  59         if (close(pipefd[1]) == -1) {
  60             // Close unused write end
  61             perror("close");
  62             exit(EXIT_FAILURE);
  63         }
  64 
  65         while (read(pipefd[0], &buf, 1) > 0) {
  66             if (write(STDOUT_FILENO, &buf, 1) != 1)
  67             {
  68                 perror("write");
  69                 exit(EXIT_FAILURE);
  70             }
  71 
  72             if(buf == '\n')
  73             {
  74                 break;
  75             }
  76         }
  77 
  78         exit(EXIT_SUCCESS);
  79     }
  80     else
  81     {
  82         // Parent
  83 
  84         if (close(pipefd[0]) == -1) {
  85             // Close unused read end
  86             perror("close");
  87             exit(EXIT_FAILURE);
  88         }
  89 
  90         LOG_ID("PID is %jd\n", (intmax_t) getpid());
  91         const char *str = "Hello, World!\n\0";
  92         write(pipefd[PIPE_WRITE_END], str, strlen(str));
  93 
  94         do
  95         {
  96             if(waitpid(cpid, &wstatus, WUNTRACED | WCONTINUED) == -1)
  97             {
  98                 perror("waitpid");
  99                 exit(EXIT_FAILURE);
 100             }
 101 
 102             if (WIFEXITED(wstatus))
 103             {
 104                 LOG_ID("Child exited with status %d\n", WEXITSTATUS(wstatus));
 105             }
 106             else if (WIFSIGNALED(wstatus))
 107             {
 108                 LOG_ID("Child killed by signal %d\n", WTERMSIG(wstatus));
 109             }
 110             else if (WIFSTOPPED(wstatus))
 111             {
 112                 LOG_ID("Child stopped by signal %d\n", WSTOPSIG(wstatus));
 113             }
 114             else if (WIFCONTINUED(wstatus))
 115             {
 116                 LOG_ID("Child continued\n");
 117             }
 118 
 119         } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
 120         exit(EXIT_SUCCESS);
 121     }
 122 
 123     exit(EXIT_SUCCESS);
 124 }