[제12장] 프로세스 간 통신 : 파이프

정보 | 2007/06/25 19:06

=================================================================
  * Subject : [제12장] 프로세스 간 통신 : 파이프
  * Writer: w0rm9 (research.hackerschool.org)
  * Date: 2004/02/15
=================================================================

/* 스터디 내용을 중심으로 정리했고, 소스는 몽이님이 사용했던 소스 및 수정한 소스를 사용했습니다.
 */


0x01. 프로세스 파이프

■ popen
사용법)
#include <stdio.h>

FILE *popen(const char *command, const char *open_mode);
int pclose(FILE *stream_to_close);
=> command는 실행할 프로그램 이름이며, open_mode는 "r"과 "w"중 하나이다.
   pclose()함수는 프로세스가 끝날 때까지 대기한다.

테스트)
[w0rm9@work PIPE]$ cat popen1.c
#include <stdio.h>

int main()
{
        FILE *fp;
        char string[256];

        fp = popen("/bin/ls", "r");    // "/bin/ls"를 "r"모드로 실행. 즉, /bin/ls 의 출력 결과를 읽어들인다.

        while(fread(string, 1, 256, fp))   // 읽어들인 결과를 string으로 읽어와서
                printf("%s", string);    // 출력

        pclose(fp);
}
[w0rm9@work PIPE]$ gcc -o popen1 popen1.c
[w0rm9@work PIPE]$ ./popen1
popen1
popen1.c
popen2
popen2.c
[w0rm9@work PIPE]$ cat popen2.c
#include <stdio.h>

int main()
{
        FILE *fp;
        char buf[256];

        sprintf(buf, "사랑해\n");
        fp = popen("/bin/cat > text", "w");   // "/bin/cat > text"를 "w"모드로 실행. /bin/cat > text 에 무언가를 보낸다.
        if(fp != NULL){
                fwrite(buf, sizeof(char), strlen(buf), fp); // buf의 내용을 /bin/cat > text에 쓴다.
                pclose(fp);
        }
}
[w0rm9@work PIPE]$ gcc -o popen2 popen2.c
[w0rm9@work PIPE]$ ./popen2
[w0rm9@work PIPE]$ ls -al text
-rw-rw-r--    1 w0rm9    w0rm9           7  2월 16 10:43 text
[w0rm9@work PIPE]$ cat text
사랑해


0x02. 파이프 호출

■ pipe
사용법)
#include <unistd.h>

int pipe(int file_descriptor[2]);
=> file_descriptor[1]에는 데이터 저장, file_descriptor[0]에는 데이터 읽기

테스트)
[w0rm9@work PIPE]$ cat pipe.c
#include <stdio.h>
#include <unistd.h>

int main()
{
        int pipes[2];
        char buffer[1024], string[1024];
        pipe(pipes);      // 1. pipe()호출

        if(fork() ==0){
                sleep(3);
                read(pipes[0], buffer, sizeof(buffer));  // 4. pipes[0]를 buffer가 읽어온다.
                printf("자식 : %s\n", buffer);   // 5. 읽은 buffer내용을 출력한다.
        }

        else{
                printf("부모 : ");
                fgets(string, 1024, stdin);   // 2. string에 표준입력한다.
                write(pipes[1], string, strlen(string)); // 3. string의 내용을 pipes[1]에 쓴다.
                sleep(3);
        }

}
[w0rm9@work PIPE]$ gcc -o pipe pipe.c
[w0rm9@work PIPE]$ ./pipe
부모 : 사랑해^^
자식 : 사랑해^^

■ dup, dup2
사용법)
#include <unistd.h>

int dup(int file_descriptor);
int dup2(int file_descriptor_one, int file_descriptor_one);
=> dup()는 새로운 파일 기술자를 연다. 가장 낮은 유효한 값을 사용하여 반환
   dup2()는 새로운 파일 기술자를 지정하여 반환할 수 있다.

테스트)
[w0rm9@work PIPE]$ cat dup.c
#include <stdio.h>
#include <fcntl.h>

int main()
{
        int a, b, c;

        a = open("/etc/passwd", O_RDONLY);
        b = dup(a);
        c = dup2(a, 100);

        printf("a = %d\n", a);
        printf("b = %d\n", b);
        printf("c = %d\n", c);

        close(a);
        close(b);
}
[w0rm9@work PIPE]$ gcc -o dup dup.c
[w0rm9@work PIPE]$ ./dup
a = 3      // open()의한 파일기술자 3
b = 4      // 0은 표준입력, 1은 표준출력, 2은 표준에러, open()의한 파일기술자 3, 가장 낮은 유효한 값은 4
c = 100      // 직접 지정해준 파일기술자 100
[w0rm9@work PIPE]$ cat dup2.c
#include <fcntl.h>

main()
{
        int a;

        a = open("love", O_WRONLY|O_CREAT);
        dup2(a, 1);    // 표준출력을 a에 복제함.

        printf("사랑해~~\n");   // printf()에 의한 표준출력이 a로 됨
}
[w0rm9@work PIPE]$ gcc -o dup2 dup2.c
[w0rm9@work PIPE]$ ./dup2
[w0rm9@work PIPE]$ cat love
사랑해~~


0x03. 명명 파이프 : FIFO
popen()의 단점인 한 프로세스와 popen()의해 실행된 프로세스간의 통신에서 모든 프로세스가 명명 파이프를 통해 통신가능

사용법)
#include <sys/types.h>
#include <sys/stat.h>

int mkfifo(const char *filename, mode_t mode);
int mknod(const char *filename, mode_t mode | S_IFIFO, (dev_t) 0);
=> 명명 파이프를 mode와 filename를 참조하여 생성한다.

테스트)
[w0rm9@work PIPE]$ cat fifo1.c
#include <stdio.h>
#include <fcntl.h>

int main()
{
        int pipe_fd;
        mkfifo("/tmp/fifo_tmp", 0777);

        pipe_fd = open("/tmp/fifo_tmp", O_WRONLY);  // 명명 파이프를 생성

        write(pipe_fd, "사랑해", 7);    // 명명 파이프를 통해 쓴다.

        close(pipe_fd);
}
[w0rm9@work PIPE]$ gcc -o fifo1 fifo1.c
[w0rm9@work PIPE]$ cat fifo2.c
#include <stdio.h>
#include <fcntl.h>

int main()
{
        int pipe_fd;
        char string[16];

        pipe_fd = open("/tmp/fifo_tmp", O_RDONLY);  // 명명 파이프를 연다.

        read(pipe_fd, string, 7);    // 읽어들인다.

        printf("%s\n", string);

        close(pipe_fd);
}
[w0rm9@work PIPE]$ gcc -o fifo2 fifo2.c
[w0rm9@work PIPE]$ ./fifo1 &
[1] 15686
[w0rm9@work PIPE]$ ./fifo2
사랑해
[1]+  Done                    ./fifo1


_eof_

Trackback Address :: http://badnom.com/trackback/294 관련글 쓰기
Name
Password
Homepage
Secret
< PREV |  1  |  ...  825  |  826  |  827  |  828  |  829  |  830  |  831  |  832  |  833  |  ...  1058  |  NEXT >