C/Linux

[C] 2개의 파이프를 사용한 양방향 통신 프로그램 구현하기

김호록님 2023. 1. 3. 19:48

파이프를 이용한 양방향 통신

2개의 파이프를 이용하여 부모와 자식 프로세스 사이에 양방향 통신을 할 수 있는 프로그램을 만들어봅시다.

프로그램의 동작

  1. 부모 프로세스는 표준 입력으로 텍스트 데이터를 받는다.
  2. 자신이 받은 텍스트를 파이프로 자식에게 전송한다.
  3. 자식은 부모가 전송한 텍스트를 받아 모든 문자를 대문자로 변경한다.
  4. 부모가 보낸 파이프와 다른 파이프로 부모에게 변경한 결과를 보낸다.
  5. 부모는 자식이 반환한 문자열을 화면에 출력하고 다시 루프에서 대기한다.

실행결과

이 프로그램은 영어 문자열을 입력했을 때, 소문자를 대문자로 바꿔준다.

#include <ctype.h>
#include <errno.h>
#include <stdarg.h> 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define BUF_SIZE 1000

void fatal(const char *msg) {
  perror(msg);
  exit(EXIT_FAILURE);
}

int main(void) {
  int fd[2];
  int fd2[2];
  char buf[BUF_SIZE];
  ssize_t numRead, numPaRead;

  if (pipe(fd) || pipe(fd2) == -1){
    fatal("pipe");
  }

  switch (fork()) {
  case -1:
    fatal("fork");
      
  case 0:
    if (close(fd[1]) == -1 || close(fd2[0]) == -1)
      fatal("close - child");
    
    for (;;) {
      numRead = read(fd[0], buf, BUF_SIZE);
      if (numRead == -1){
        fatal("child1 read");
      }
      if (numRead == 0){
        break;
      }      
      for (int i = 0; i < numRead; i++) {
        buf[i] = toupper(buf[i]);
      } 
      if (write(fd2[1], buf, numRead) != numRead) {
        fatal("child - partial/failed write");
      }       
    }
    default: 
      if (close(fd[0]) == -1)
      {
        fatal("close - parent1");
      }        
      if (close(fd2[1]) == -1){
        fatal("close - parent2");
      }
      
      for (;;) {
        fgets(buf, BUF_SIZE, stdin);
        if(write(fd[1], buf, strlen(buf)) != strlen(buf)) {
          fatal("parent - write");
        }    
        numPaRead = read(fd2[0], buf, BUF_SIZE) != BUF_SIZE;
        if(numPaRead == -1) {
          fatal("parent - read");
        }          
        if (numPaRead == 0) {
          break;
        }
        printf("%s\n", buf);
      }      
  }
  return 0;
}