파이프를 통해서 파일 복사하기

ratmhun의 이미지

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

#define PERMS 0666

int main(int argc, char **argv)
{
	void fatal(char *);
	int object;
	char buf[BUFSIZ];
	int pfd[2];
	int n, status;
	pid_t pid;
	
	
	if(argc < 2)
	{
		puts("Usage: a.out source object");
		exit(1);
	}

	if(pipe(pfd) < 0)
		fatal("pipe");

	if((pid = fork()) < 0)
		fatal("fork");

	if(pid == 0)
	{
		dup2(pfd[1], 1);
		close(pfd[0]);

		execl("/bin/cat", "cat", argv[1], 0);
		perror("exec");
		_exit(127);
	}
	close(pfd[1]);
 	if((object = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, PERMS)) < 0)
		fatal("write open");
	if((n = read(pfd[0], buf, BUFSIZ)) < 0)
		fatal("read");
	printf("%s\n", buf);

	write(object, buf, n);
	
	close(pfd[0]);

	waitpid(pid, &status, 0);
	return 0;
}

void fatal(char *error_name)
{
	perror(error_name);
	exit(1);
}

말 그대로 pipe()를 이용해서 파일을 복사하는 프로그램입니다. 보시다시피 읽기 파일과 쓰기 파일을 열어서 읽기 파일의 내용을 쓰기 파일에 저장하는 단순한 원리의 프로그램을 수정했습니다. 이유는 단순히 pipe(pfd);를 쓰기 위해서입니다.

좀 조잡하네요. 파이프를 통해서 파일을 복사할 수 있는 프로그램으로 좀더 단순하게 만들 수 있는 방법은 없나요?

익명 사용자의 이미지

좋은 프로그램 연습을 하셨네요.

이 프로그램 패턴은 유닉스 프로그램을 하는한 두고두고 써먹게 될것입니다.

cinsk의 이미지

$ info libc 'function index' popen
ratmhun의 이미지

답변 감사합니다.
popen을 이용해서 쉘을 실행시키기 보다는 pipe()에서 사용할 수 있는 두개의 파일 디스크립터(읽기/쓰기)를 활용하고 싶습니다.

mtorange의 이미지

좀 다른 내용이지만..

제목만 보고 이런걸 생각했습니다.

mkfifo /tmp/pipe ; cat source > /tmp/pipe &; cat /tmp/pipe >destination