pipe는 이름을 없어 parent, child process만 통신이 가능하다. 이를 보안한게 named pipe인데, fifo라고도 한다. 책은 다른 유닉스 버전으로 작성하여, linux에 맞게 수정했다. 결론적으로 pipe와 비슷하고 더 쉽다.
#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <sys/wait.h> #include <string.h> #include <sys/stat.h> #include <unistd.h> #define FIFO1 "/tmp/fifo.1" #define FIFO2 "/tmp/fifo.2" #define MAXLINE 100 void client(int, int), server(int, int); void server(int readfd, int writefd){ /* char buff[MAXLINE]; int n; n = read(readfd, buff, MAXLINE); printf("서버가 읽은 data는 %s\n",buff); // 샘플 테스트용.. */ int fd; ssize_t n; char buff[MAXLINE+1]; /* 4read pathname from IPC channel */ if ( (n = read(readfd, buff, MAXLINE)) == 0) perror("end-of-file while reading pathname"); buff[n] = '\0'; /* null terminate pathname */ if ( (fd = open(buff, O_RDONLY)) < 0) { /* 4error: must tell client */ snprintf(buff + n, sizeof(buff) - n, ": can't open, %s\n", strerror(errno)); n = strlen(buff); write(writefd, buff, n); } else { /* 4open succeeded: copy file to IPC channel */ while ( (n = read(fd, buff, MAXLINE)) > 0) write(writefd, buff, n); close(fd); } } void client(int readfd, int writefd) { size_t len; ssize_t n; char buff[MAXLINE]; /* 4read pathname */ fgets(buff, MAXLINE, stdin); len = strlen(buff); /* fgets() guarantees null byte at end */ if (buff[len-1] == '\n') len--; /* delete newline from fgets() */ /* 4write pathname to IPC channel */ write(writefd, buff, len); /* 4read from IPC, write to standard output */ while ( (n = read(readfd, buff, MAXLINE)) > 0) write(STDOUT_FILENO, buff, n); } int main(int argc, char **argv) { int readfd, writefd; pid_t childpid; /* 4create two FIFOs; OK if they already exist */ if ((mkfifo(FIFO1, 0666) < 0) && (errno != EEXIST)) printf("can't create %s", FIFO1); if ((mkfifo(FIFO2, 0666) < 0) && (errno != EEXIST)) { unlink(FIFO1); printf("can't create %s", FIFO2); } if ( (childpid = fork()) == 0) { /* child */ readfd = open(FIFO1, O_RDONLY, 0); writefd = open(FIFO2, O_WRONLY, 0); server(readfd, writefd); exit(0); } /* 4parent */ writefd = open(FIFO1, O_WRONLY, 0); readfd = open(FIFO2, O_RDONLY, 0); client(readfd, writefd); waitpid(childpid, NULL, 0); /* wait for child to terminate */ close(readfd); close(writefd); unlink(FIFO1); unlink(FIFO2); exit(0); }
pi@raspberrypi:~/Project/cCode/IPC $ ls a.out fifo.c simplepipe.c unpv22e fduplex.c pipe.c test.txt unpv22e.tar pi@raspberrypi:~/Project/cCode/IPC $ cat test.txt 안녕하세요. hello. pi@raspberrypi:~/Project/cCode/IPC $ ./a.out ./test.txt 안녕하세요. hello. pi@raspberrypi:~/Project/cCode/IPC $
이 장에 여러 내용도 많은데 일단 다른 유닉스 버전도 보이고 시간도 없어 다음 장으로 넘어간다.