2. Pipes

  1. O exemplo abaixo ilustra a utilização de pipes dentro de um mesmo processo. Rode-o e explique o seu funcionamento.

    main()
    {
       int pipefd[2], n;
       char buff[100];
       
       if (pipe(pipefd) < 0)
          printf("pipe error");
    
       printf("read fd = %d, write fd = %d\n", pipefd[0], pipefd[1]);
       if (write(pipefd[1], "hello world\n", 12) != 12)
          printf("write error");
    
       if ((n = read(pipefd[0], buff, sizeof(buff))) <= 0)
          printf("read error");
    
       write(1, buff, n);      /* fd 1 = stdout */
    
       exit(0);
    }
  2. Exemplo abaixo mostra um sistema produtor/consumidor. Compile-o e rode. Explique o funcionamento do sistema, detalhando as ações do pai e do filho. Faça um diagrama (edite o desenho com caracteres ASCII) explicando o funcionamento.

    #include stdio.h
    #include errno.h 
    #include sys/errno.h 
    #define MAXBUFF 1024 main() 
    {
        int childpid, pipe1[2], pipe2[2]; 
        printf("Inicio do programa Client_Server\n\n");
        if (pipe(pipe1) menor 0 || pipe(pipe2) < 0)
        { 
           perror("can't create pipes");
           exit(0); 
        } 
        printf("Os pipes foram criados corretamente\n"); 
        if ((childpid = fork()) < 0) 
        {
           perror("can't fork"); 
        } 
        else if (childpid > 0) 
        { 
          /* parent */
          close(pipe1[0]); 
          close(pipe2[1]); 
          client(pipe2[0], pipe1[1]); 
          while (wait((int *) 0) != childpid); 
          /* wait for child */ 
          close(pipe1[1]); 
          close(pipe2[0]); 
          exit(0); 
        } 
        else 
       {
         /* child */ 
         close(pipe1[1]); 
         close(pipe2[0]); 
         server(pipe1[0], pipe2[1]); 
         close(pipe1[0]); 
         close(pipe2[1]); 
         exit(0); 
       }
    }
     /* Esta e' a funcao cliente */ 
    
    client(int readfd, intwritefd) 
    { 
       char buff[MAXBUFF];  
       int n;       
    /* 
    * Read the filename from standard input, 
    * write it to the IPC descriptor. 
    */ 
       if (fgets(buff, MAXBUFF, stdin) == NULL) 
          perror("client: filename read error"); 
    
       n = strlen(buff); 
       if (buff[n-1] == '\n') 
          n--;     /* ignore newline from fgets() */ 
    
       if (write(writefd, buff, n) != n) 
          perror("client: filename write error"); 
    
    /* 
    * Read the data from the IPC descriptor and write 
    * to standard output. 
    */ 
    
       while ((n = read(readfd, buff, MAXBUFF)) > 0) 
       if (write(1, buff, n) != n)             /* fd 1 = stdout */ 
          perror("client: data write error"); 
       if (n m < 0) 
       { 
          perror("client: data read error"); 
       } 
    } 
    
    /* Esta e' a funcao servidor */ 
    server(int readfd, int writefd) 
    { 
        char buff[MAXBUFF]; 
        char errmesg[256]; 
        int n; 
        long int fd; 
        extern int errno; 
        extern char *sys_errlist[]; 
    
    /* 
    * Read the filename from the IPC descriptor. 
    */
    
        if ((n = read(readfd, buff, MAXBUFF)) < = 0) 
           perror("server: filename read error"); 
        buff[n] = '\0';      /* null terminate filename */ 
        if ((fd = open(buff, 0)) < 0) 
        { 
          /* 
           * Error. Format an error message and send it back 
           * to the client.
           */ 
           sprintf(errmesg, ":can't open.\n"); 
           strcat(buff, errmesg); 
           n = strlen(buff); 
           if (write(writefd, buff, n) != n) 
             perror("server: errmesg write error"); 
        } 
        else 
        { 
          /* 
           * Read the data from the file and write to 
           * the IPC descriptor. 
           */ 
           while ((n = read(fd, buff, MAXBUFF)) > 0) 
           if (write(writefd, buff, n) != n) 
              perror("server: data write error"); 
           if (n < 0) 
           {
              perror("server: read error"); 
           } 
        } 
    } 
  3. Quais as limitações deste mecanismo de comunicação entre processos para a implementação de pares servidor/cliente?

  4. Modifique o exemplo de modo que o servidor seja uma calcuradora com as 4 operações aritméticas básicas. Projete um sistema de entrada/saída adequado.