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 $
이 장에 여러 내용도 많은데 일단 다른 유닉스 버전도 보이고 시간도 없어 다음 장으로 넘어간다.