span class=postbodyman page에 보면 pipe와 dup2에 대해서 너무나 잘 설명되어 있습니다.
br /
이 글은 man page를 보고서 pipe가 어떻게 생성되며 언제 그것을
br /
닫게 해야 하고 dup2에 의해서 생성된 fd는 close되고 생성된다는 것과
br /
그 밖에 여러가지 사항들을 예제로 표현한겁니다.
br /
dup2는 Win32에서도 되므로 dup2를 이용해서 debug message를
br /
redirection하면 요긴하겠네요.
br /
단, pipe함수는 Win32에 없는듯 한데 혹시 Win32에서는
br /
pipe를 어떻게 사용하는지 아시는 분은 리플달아주시면 다른분들께
br /
굉장히 유용하겠네요...
br /
중간쯤 보시면 sleep을 준 부분이 있습니다.
br /
왜 줘야 할까요? 그리고 그것을 sleep없이 block되지 않게 하는 방법은
br /
어떤게 있을까요?
br /
한번쯤 생각해보시면 나중에 요긴할겁니다.
br /
또한 이것을 통해서 보통 debug함수를 첫 부분에서 fork하면서 감싸는 방법이
br /
있습니다. 간단하겠죠? 그리고 왜? 제가 3단 fork 및 2회의 exec를 했을까요?
br /
br /
/spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=code
br /
/*
br /
Copyright (c) Information Equipment co.,LTD.
br /
All right reserved.
br /
Code by JaeHyuk Cho lt;mailto: a href=mailto:minzkn@infoeq.comminzkn@infoeq.com/a gt; Made in KOREA
br /
http://minzkn.pe.ky
br /
*/
br /
br /
#include lt;sys/types.hgt;
br /
#include lt;stdio.hgt;
br /
#include lt;stdlib.hgt;
br /
#include lt;wait.hgt;
br /
#include lt;unistd.hgt;
br /
br /
int main(int s_Argc, char *s_Argv[])
br /
{
br /
int s_Handles[2], s_Fork, s_ReadBytes;
br /
char *s_Exec0[] = { ls, -al, (char *)0 };
br /
char *s_Exec1[] = { /sbin/ifconfig, (char *)0 };
br /
unsigned char s_Buffer[ 32 lt;lt; 10 ];
br /
if(pipe(amp;s_Handles[0]) == 0)
br /
{
br /
nbsp; fprintf(stdout, -[ FORK ]---------------------------------------------------------------\n);
br /
nbsp; s_Fork = fork();
br /
nbsp; if(s_Fork == 0)
br /
nbsp; {
br /
nbsp; nbsp;dup2(s_Handles[1], 1 /* stdout */);
br /
nbsp; nbsp;close(s_Handles[0]);
br /
nbsp; nbsp;close(s_Handles[1]);
br /
nbsp; nbsp;s_Fork = fork();
br /
nbsp; nbsp;if(s_Fork == 0)
br /
nbsp; nbsp;{
br /
nbsp; nbsp; fprintf(stdout, \ns_Exec0 run.\n);
br /
nbsp; nbsp; s_Fork = fork();
br /
nbsp; nbsp; if(s_Fork == 0)
br /
nbsp; nbsp; {
br /
nbsp; nbsp; nbsp;execvp(amp;s_Exec0[0][0], s_Exec0);
br /
nbsp; nbsp; nbsp;exit(0);
br /
nbsp; nbsp; }
br /
nbsp; nbsp; else wait(0);
br /
nbsp; nbsp; fprintf(stdout, \ns_Exec1 run.\n);
br /
nbsp; nbsp; s_Fork = fork();
br /
nbsp; nbsp; if(s_Fork == 0)
br /
nbsp; nbsp; {
br /
nbsp; nbsp; nbsp;execvp(amp;s_Exec1[0][0], s_Exec1);
br /
nbsp; nbsp; nbsp;exit(0);
br /
nbsp; nbsp; }
br /
nbsp; nbsp; else wait(0);
br /
nbsp; nbsp; fprintf(stderr /* !!!! */, \nEnd of exec\n);
br /
nbsp; nbsp;}
br /
nbsp; nbsp;exit(0);
br /
nbsp; }
br /
nbsp; else wait(0);
br /
nbsp; #if 1
br /
nbsp; fprintf(stdout, -[ SLEEP ]--------------------------------------------------------------\n);
br /
nbsp; sleep(1);
br /
nbsp; #endif
br /
nbsp; fprintf(stdout, -[ PIPE ]---------------------------------------------------------------\n);
br /
nbsp; do
br /
nbsp; {
br /
nbsp; nbsp;s_ReadBytes = read(s_Handles[0], amp;s_Buffer[0], sizeof(s_Buffer) - 1);
br /
nbsp; nbsp;if(s_ReadBytes gt; 0)
br /
nbsp; nbsp;{
br /
nbsp; nbsp; s_Buffer[s_ReadBytes] = '\0';
br /
nbsp; nbsp; fprintf(stdout, %s, (char *)(amp;s_Buffer[0]));
br /
nbsp; nbsp;}
br /
nbsp; }while(s_ReadBytes == sizeof(s_Buffer));
br /
nbsp; fflush(stdout);
br /
nbsp; close(s_Handles[0]);
br /
nbsp; close(s_Handles[1]);
br /
nbsp; fprintf(stdout, -[ EOF ]---------------------------------------------------------------\n);
br /
}
br /
return(0);
br /
}
br /
br /
/* End of source */
br /
/td /tr/tbody/tablespan class=postbody
br /
br /
또 다른 예제
br /
/spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=code/*
br /
nbsp; Copyright (C) Information Equipment co.,LTD
br /
nbsp; All rights reserved.
br /
nbsp; Code by JaeHyuk Cho lt;mailto:minzkn@infoeq.comgt;
br /
nbsp; CVSTAG=$Header$
br /
*/
br /
br /
#include lt;sys/types.hgt;
br /
#include lt;stdio.hgt;
br /
#include lt;stdlib.hgt;
br /
#include lt;wait.hgt;
br /
#include lt;unistd.hgt;
br /
br /
int main(void)
br /
{
br /
int s_pipe_stdout[2];
br /
pid_t s_pid;
br /
ssize_t s_read_bytes;
br /
char *s_exec[] = {ls, -al, (char *)0};
br /
unsigned char s_buffer[ 4 lt;lt; 10 ];
br /
if(pipe((int *)(amp;s_pipe_stdout[0])) == 0)
br /
{
br /
nbsp; s_pid = fork();
br /
nbsp; if(s_pid == ((pid_t)0))
br /
nbsp; {
br /
nbsp; nbsp;(void)dup2(s_pipe_stdout[1], STDOUT_FILENO);
br /
nbsp; nbsp;(void)close(s_pipe_stdout[0]);
br /
nbsp; nbsp;(void)close(s_pipe_stdout[1]);
br /
nbsp; nbsp;(void)execvp(amp;s_exec[0][0], s_exec);
br /
nbsp; nbsp;exit((int)1);
br /
nbsp; }
br /
nbsp; else (void)wait((int *)0);
br /
br /
nbsp; (void)fputs(\x1b[1;37mstdout {\x1b[1;33m\n, stdout);
br /
nbsp; do
br /
nbsp; {
br /
nbsp; nbsp;s_read_bytes = read(s_pipe_stdout[0], (void *)(amp;s_buffer[0]), (size_t)(sizeof(s_buffer) - 1));
br /
nbsp; nbsp;if(s_read_bytes gt; ((ssize_t)0))
br /
nbsp; nbsp;{
br /
nbsp; nbsp; s_buffer[s_read_bytes] = (unsigned char)'\0';
br /
nbsp; nbsp; (void)fprintf(stdout, %s, (char *)(amp;s_buffer[0]));
br /
nbsp; nbsp; (void)fflush(stdout);
br /
nbsp; nbsp;}
br /
nbsp; }while(s_read_bytes == ((ssize_t)sizeof(s_buffer)));
br /
nbsp; (void)fputs(\x1b[1;37m}\x1b[0m\n, stdout);
br /
br /
nbsp; (void)close(s_pipe_stdout[0]);
br /
nbsp; (void)close(s_pipe_stdout[1]);
br /
}
br /
else (void)perror(pipe_stdout);
br /
return(0);
br /
}
br /
br /
/* vim: set expandtab: */
br /
/* End of source *//td /tr/tbody/tablespan class=postbody
br /
br /
또다른 예제
br /
/spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=code/*
br /
nbsp; Copyright (C) Information Equipment co.,LTD
br /
nbsp; All rights reserved.
br /
nbsp; Code by JaeHyuk Cho lt;mailto:minzkn@infoeq.comgt;
br /
nbsp; CVSTAG=$Header$
br /
*/
br /
br /
#include lt;stdio.hgt;
br /
br /
int main(void)
br /
{
br /
FILE *s_pipe;
br /
char *s_line;
br /
unsigned char s_buffer[ 32 lt;lt; 10 ];
br /
int s_line_count = 0;
br /
s_pipe = popen(/bin/ls -al, r);
br /
if(s_pipe != ((FILE *)0))
br /
{
br /
nbsp; do
br /
nbsp; {
br /
nbsp; nbsp;s_line = fgets((char *)(amp;s_buffer[0]), sizeof(s_buffer), s_pipe);
br /
nbsp; nbsp;if(s_line == (char *)0)break;
br /
nbsp; nbsp;s_line_count++;
br /
nbsp; nbsp;(void)fprintf(stdout, \x1b[1;33m%5d: \x1b[1;0m%s, s_line_count, s_line);
br /
nbsp; nbsp;(void)fflush(stdout);
br /
nbsp; }while(1);
br /
nbsp; (void)pclose(s_pipe);
br /
}
br /
else (void)perror(popen);
br /
return(0);
br /
}
br /
br /
/* vim: set expandtab: */
br /
/* End of source *//td /tr/tbody/tablespan class=postbody
br /
br /
br /
마지막으로 아래의 예제는 종합적으로 어떻게 실제 사용할수 있을지 현실적인 예제로 만들어 본겁니다. 아래의 예제는 외부 실행파일 grep 명령을 활용하여 grep 의 기능을 C에서 사용하도록 함수화 한것입니다.
br /
br /
/spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=code/*
br /
nbsp; Copyright (C) Information Equipment co.,LTD
br /
nbsp; All rights reserved.
br /
nbsp; Code by JaeHyuk Cho lt;mailto:minzkn@infoeq.comgt;
br /
nbsp; CVSTAG=$Id$
br /
*/
br /
br /
#include lt;sys/types.hgt;
br /
#include lt;stdio.hgt;
br /
#include lt;stdlib.hgt;
br /
#include lt;string.hgt;
br /
#include lt;wait.hgt;
br /
#include lt;unistd.hgt;
br /
br /
static ssize_t grep_ext(void *s_data, size_t s_size, const char *s_string, char *s_word)
br /
{
br /
ssize_t s_result = (ssize_t)(-1);
br /
int s_pipe_stdin[2];
br /
int s_pipe_stdout[2];
br /
pid_t s_pid;
br /
char *s_exec[] = {grep, -i, (char *)0, (char *)0};
br /
s_exec[2] = s_word;
br /
if(pipe((int *)(amp;s_pipe_stdin[0])) != 0)
br /
{
br /
nbsp; (void)perror(can not open pipe (stdin));
br /
nbsp; return((ssize_t)(-1));
br /
}
br /
if(pipe((int *)(amp;s_pipe_stdout[0])) != 0)
br /
{
br /
nbsp; (void)perror(can not open pipe (stdout));
br /
nbsp; (void)close(s_pipe_stdin[0]);
br /
nbsp; (void)close(s_pipe_stdin[1]);
br /
nbsp; return((ssize_t)(-1));
br /
}
br /
s_pid = fork();
br /
if(s_pid == ((pid_t)(-1)))
br /
{
br /
nbsp; (void)perror(fork error);
br /
nbsp; (void)close(s_pipe_stdin[0]);
br /
nbsp; (void)close(s_pipe_stdin[1]);
br /
nbsp; (void)close(s_pipe_stdout[0]);
br /
nbsp; (void)close(s_pipe_stdout[1]);
br /
nbsp; return((ssize_t)(-1));
br /
}
br /
if(s_pid == ((pid_t)0))
br /
{
br /
nbsp; (void)dup2(s_pipe_stdin[0], STDIN_FILENO);
br /
nbsp; (void)dup2(s_pipe_stdout[1], STDOUT_FILENO);
br /
nbsp; (void)close(s_pipe_stdin[0]);
br /
nbsp; (void)close(s_pipe_stdin[1]);
br /
nbsp; (void)close(s_pipe_stdout[0]);
br /
nbsp; (void)close(s_pipe_stdout[1]);
br /
nbsp; (void)execvp(amp;s_exec[0][0], s_exec);
br /
nbsp; exit((int)1);
br /
nbsp; return((ssize_t)(-1));
br /
}
br /
(void)close(s_pipe_stdin[0]);
br /
(void)close(s_pipe_stdout[1]);
br /
s_result = write(s_pipe_stdin[1], (void *)s_string, strlen(s_string));
br /
(void)close(s_pipe_stdin[1]);
br /
if(s_result gt; ((ssize_t)0))s_result = read(s_pipe_stdout[0], s_data, s_size);
br /
(void)wait((int *)0);
br /
(void)close(s_pipe_stdout[0]);
br /
return(s_result);
br /
}
br /
br /
int main(int s_argc, char **s_argv)
br /
{
br /
static const char c_org[] = {
br /
nbsp; THIS is test\n
br /
nbsp; THERE is test\n
br /
nbsp; This is test\n
br /
nbsp; There is test\n
br /
nbsp; this is test\n
br /
nbsp; there is test\n
br /
};
br /
char s_buffer[ 32 lt;lt; 10 ];
br /
ssize_t s_size;
br /
s_size = grep_ext((void *)(amp;s_buffer[0]), sizeof(s_buffer) - 1, c_org, this);
br /
if(s_size gt; ((ssize_t)0))
br /
{
br /
nbsp; s_buffer[s_size] = '\0';
br /
nbsp; (void)fprintf(stdout, %ld/%d [%s]\n, (long)s_size, (int)strlen(c_org), s_buffer);
br /
}
br /
else (void)fprintf(stderr, oops\n);
br /
return(0);
br /
}
br /
br /
/* vim: set expandtab: */
br /
/* End of source *//td /tr/tbody/table
받은 트랙백이 없고,
댓글 2개가 달렸습니다.

글
댓글을 달아 주세요
댓글 RSS 주소 : http://blog.minzkn.com/rss/comment/54댓글 ATOM 주소 : http://blog.minzkn.com/atom/comment/54
man 페이지 번역해 놓은게 있어서 트랙백 겁니다. :-)
3단 2단 처리한건, 시그널 처리 때문이겠죠 ?