cat < a.txt | grep ^d 를 구현하려 하는데 정상종료가 되질 않습니다.

tremendous의 이미지

child를 2개 만들어 1번째 child는 cat < a.txt를 실행해서 pipe로 넘기고, 2번째 child는 pipe에서 입력받아 grep ^d를 실행 후 결과를 출력하는건데요

결과를 출력하긴 하는데 종료가 되질 않네요..

왜 그런건가요?

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
 
int main()
{
	int pid;
	int fd;
	int fd2;
	int p[2];
	int i;
	int monitor;
	pipe(p);
 
	fd = open("a.txt",O_RDONLY);
 
	for(i=0 ; i<2 ; i++)
	{
		switch(pid=fork())
		{
		case 0:
		if(i==0)
		{
			close(1);
			close(p[0]);
			dup2(p[1],1);
			close(0);
			close(p[1]);
			dup2(fd,0);
 
			execlp("cat","cat",NULL);
		}
		else
		{
			close(p[1]);
			close(0);
			dup2(p[0],0);
 
			execlp("grep","grep","^d",NULL);
		}
			break;
		default:
			waitpid(pid,NULL,0);
			break;
		}
	}
	return 0;
}
shint의 이미지

하튼. waitpid 전후로. p[1]을 닫아주니 됩니다. (아마도. 파이프의 출력을 닫아서 인거 같습니다)
잘 아시는 분이 주석 달아주세요. 전. 내용은 잘모릅니다. ㅡ_ㅡ;;;

유닉스 시스템 프로그래밍 SVR4
O'REILLY 한빛미디어

345p 410p 참고 했습니다.

페도라13에서
gcc -o test test.c 로 컴파일
./test 실행

[%
#include
#include
#include
#include

#include
#include

static int main_id;
void fn_id()
{
if(main_id == getppid())
{
printf("\t\t");
}

printf(" ppid [%d]", getppid());
printf(" main id [%d] -- ", getpid());
}

void fn_end()
{
printf("\n");
}

int main()
{
int pid;
int fd;
int fd2;
int i;
int monitor;
int state;

int p[2];
char line[100];
// char *arg1[100] = {"cat"};
// char *arg2[100] = {"grep", "^d"};
char *arg1[2];
char *arg2[3];

arg1[0] = "cat";
arg1[1] = NULL;

arg2[0] = "grep";
arg2[1] = "^d";
arg2[2] = NULL;

system("clear");

pipe(p); //create pipe

main_id = getpid();

fn_id(); printf("pipe [%d] [%d]", p[0], p[1]); fn_end();

fd = open("a.txt", O_RDWR);
fn_id(); printf("open fd [%d]", fd); fn_end();

for(i=0 ; i<2 ; i++)
{

fn_id(); printf("pre - fork : i [%d]", i); fn_end();
pid=fork();
fn_id(); printf("next - fork : i [%d] [pid:%d]", i, pid); fn_end();
if(pid == 0)
{
if(i==0)
{
fn_id(); printf("pre - cat"); fn_end();
// close(1); fn_id(); printf("close stdout"); fn_end();
// close(p[0]); fn_id(); printf("close pipe0"); fn_end();
dup2(p[1],1); fn_id(); printf("connect pipe1 to stdout"); fn_end();

// if( read(p[1], line, 100) < 0 )
// {
// perror("read0");
// _exit(1);
// }
// fn_id(); printf("line: %s\n", line);

// close(0); fn_id(); printf("close stdin"); fn_end();
// close(p[1]); fn_id(); printf("close pipe1"); fn_end();
dup2(fd,0); fn_id(); printf("connect open file to stdin"); fn_end();

// execl("/bin/cat","cat",NULL);
execvp("cat",arg1);
if( read(fd, line, 100) < 0 )
{
perror("read1");
_exit(1);
}
fn_id(); printf("line: %s\n", line);

// perror("exec");
// _exit(127);
fn_id(); printf("next - cat"); fn_end();
}
else
{
fn_id(); printf("pre - grep"); fn_end();
// close(p[1]); fn_id(); printf("close pipe1"); fn_end();
// close(0); fn_id(); printf("close stdin"); fn_end();
dup2(p[0],0); fn_id(); printf("connect pipe0 to stdin"); fn_end();

// execl((char*)"grep","grep","s",NULL);
execvp((char*)"grep", arg2);
if( read(p[0], line, 100) < 0 )
{
perror("read2");
_exit(1);
}
fn_id(); printf("line: %s\n", line);

perror("exec");
_exit(127);
fn_id(); printf("next - grep"); fn_end();
}
}
else
{
fn_id(); printf("pre - waitpid : [pid:%d]", pid); fn_end();

//close(p[1]);
// waitpid(pid,NULL,0);
waitpid(pid,&state,0);
close(p[1]);

//pid -1 : child state
//pid > 0 : process id == pid state. child
//pid = 0 : call process == group state
//pid <= -1 : process id - MAX pid state. process is child

fn_id(); printf("next - waitpid : state [%d]\n", state); fn_end();
}
}
return 0;
}

//출력 결과
ppid [1932] main id [3484] -- pipe [3] [4]
ppid [1932] main id [3484] -- open fd [5]
ppid [1932] main id [3484] -- pre - fork : i [0]
ppid [1932] main id [3484] -- next - fork : i [0] [pid:3486]
ppid [1932] main id [3484] -- pre - waitpid : [pid:3486]
ppid [3484] main id [3486] -- next - fork : i [0] [pid:0]
ppid [3484] main id [3486] -- pre - cat
ppid [1932] main id [3484] -- next - waitpid : state [0]

ppid [1932] main id [3484] -- pre - fork : i [1]
ppid [1932] main id [3484] -- next - fork : i [1] [pid:3487]
ppid [1932] main id [3484] -- pre - waitpid : [pid:3487]
ppid [3484] main id [3487] -- next - fork : i [1] [pid:0]
ppid [3484] main id [3487] -- pre - grep
ppid [3484] main id [3487] -- connect pipe0 to stdin
ppid [3484] main id [3486] -- connect pipe1 to stdout
ppid [3484] main id [3486] -- connect open file to stdin
shint
ppid [1932] main id [3484] -- next - waitpid : state [0]

저는 grep s를 사용해서.
a.txt 파일의
shint
1234
5678
중에서 shint가 출력됨.

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.