pipe(pipe, dup2, popen) 통신

Programming/C/C++ 2007/05/05 02:33 장인정신
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
크리에이티브 커먼즈 라이센스
Creative Commons License
2007/05/05 02:33 2007/05/05 02:33
받은 트랙백이 없고, 댓글 2개가 달렸습니다.

댓글+트랙백 RSS :: http://blog.minzkn.com/rss/response/54

댓글+트랙백 ATOM :: http://blog.minzkn.com/atom/response/54

트랙백 주소 :: http://blog.minzkn.com/trackback/54

트랙백 RSS :: http://blog.minzkn.com/rss/trackback/54

트랙백 ATOM :: http://blog.minzkn.com/atom/trackback/54

댓글을 달아 주세요

댓글 RSS 주소 : http://blog.minzkn.com/rss/comment/54
댓글 ATOM 주소 : http://blog.minzkn.com/atom/comment/54
  1. yundream 2007/05/08 00:53  댓글주소  수정/삭제  댓글쓰기

    man 페이지 번역해 놓은게 있어서 트랙백 겁니다. :-)

  2. yundream 2007/05/08 00:55  댓글주소  수정/삭제  댓글쓰기

    3단 2단 처리한건, 시그널 처리 때문이겠죠 ?