fifo 예제. unix network programming 55p

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 $ 

이 장에 여러 내용도 많은데 일단 다른 유닉스 버전도 보이고 시간도 없어 다음 장으로 넘어간다.

https://www.geeksforgeeks.org/named-pipe-fifo-example-c-program/

코멘트

댓글 남기기

이 사이트는 Akismet을 사용하여 스팸을 줄입니다. 댓글 데이터가 어떻게 처리되는지 알아보세요.