반응형

fdopen(3)

#include <stdio.h>

FILE *fdopen(int fd, const char *mode);

file descriptor를 stream I/O를 위해 FILE *로 변환하는 함수입니다. 처음부터 fopen(3)으로 open하지 왜 이렇게 fdopen(3)함수가 있을까요? socket(2), accept(2) 등의 socket 통신용 API들은 fopen(3)을 통해서 FILE *를 생성할 수 없기 때문입니다. fd를 fdopen(3)으로 변경하여 사용하면 많은 장점들이 있습니다. fprintf(3)와 같은 formatting함수를 사용하여 다양한 출력을 할 수 있습니다.

    예를들면, socket통신에서 accept(2)를 통해서 생성된 fd에서 데이터를 telnet/http/ftp 등과 같이 newline으로 데이터를 잘라서 parsing해서 사용하는 protocol을 구현할 때에 라인 단위로 읽기 위해서는 귀챦은 작업을 많이 해야합니다.

 그런데, fdopen(3)으로 FILE *를 얻으면 fgets(3)로 한라인씩 읽을 수 있습니다. 또한, 출력은 fprintf(fp, ".....\n", data); 형식으로 출력하면됩니다. 아주 편하게 사용할 수 있습니다. setvbuf(fd, NULL, _IOLBF, 0)함수를 통하여 new line이면 바로 전송으로 설정할 수 있습니다. 또는 fprintf(3)후에 fflush(3)를 호출하면 socket으로 데이터 전송됩니다.

 

fclose(3)를 통해 FILE *을 close하면 fd도 함께 close됩니다.

 

 

파라미터

fd
    - open(2), creat(2), socket(2), accept(2) 등으로 생성한 file descriptor입니다.
    - UNIX / LINUX에서는 socket도 파일로 인식합니다. 
      그래서 통신 시에도 send(2) 대신에 write(2)를, recv(2) 대신 read(2)를 사용해도 I/O가 발생합니다.
mode
    - ile을 open하는 목적을 설정합니다. mode는 fd의 option과도 맞아야 합니다.

 "r" : 파일을 읽기 전용으로 open합니다.
       fd는 open(2)시에 O_RDONLY 또는 O_RDWR로 flag가 설정되어 있어야 합니다.

 "r+" : 파일을 읽기 / 쓰기용으로 open합니다. 
       fd는 open(2)시에 O_RDWR로 열어야 합니다.

 "w" : 파일을 쓰기 전용으로 open합니다.
       fd는 open(2)시에 O_WRONLY 또는 O_RDWR로 열어야 합니다.
       fdopen(3)시에 파일의 크기를 0으로 초기화하지는 않습니다.

 "w+" : 파일을 읽기 / 쓰기용으로 open합니다. 
       fd는 open(2)시에 O_RDWR로 열어야 합니다.
       fdopen(3)시에 파일의 크기를 0으로 초기화하지는 않습니다.

 "a" : 파일을 append mode로 open합니다. 
       fd는 open(2)시에 O_WRONLY | O_APPEND 또는 O_RDWR | O_APPEND로 열어야 합니다.

 "a+" : 파일을 append 및 읽기 mode로 open합니다.
       fd는 open(2)시에 O_RDWR | O_APPEND로 열어야 합니다.

 

RETURN

NULL 아님
    - 정상적으로 파일이 open되었습니다.

NULL
    - 오류가 발생하였으며, 오류 내용은 errno에 설정됩니다.

 


활용 예제

 

Sample

#include <stdio.h>
#include <string.h>

#include <errno.h>

......



int main(int argc, char *argv[])
{
    FILE *fp;
    int   fd;
    char buffer[4096];

    ......

    if((fd = open("myprogram.log", O_WRONLY | O_APPEND | O_CREAT)) == -1) {
        fprintf(stderr, "log file 생성 오류: %s\n", strerror(errno));
        return 1;
    }

    ......

    if((fp = fdopen(fd, "a")) == NULL) {
        fprintf(stderr, "stream 생성 오류: %s\n", strerror(errno));
        return 1;
    }

    ......

    fprintf(fp, "%s - %s - %05d : 데이터는 %s\n", __FILE__, __func__, __LINE__, data);

    ......

    fclose(fp);
    return 0;
}

 


see also :

    File 속성 정보 및 파일 관리 Library

    Directory 정보 조회 및 관리 Library

    System Call File I/O Library

    Stream File I/O Library

 

 

 

 

반응형
블로그 이미지

자연&사람

행복한 개발자 programmer since 1995.

,