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 :
'C언어 header > stdio.h' 카테고리의 다른 글
fprintf(3) - 데이터를 format된 형태로 file로 출력 (0) | 2019.10.04 |
---|---|
printf(3) - 데이터를 format된 형태로 화면 출력 (0) | 2019.10.04 |
rename(3) - 파일명 또는 디렉토리의 이름 변경 및 위치 변경 (0) | 2019.09.24 |
remove(3) - 파일 또는 디렉토리를 삭제하는 함수 (0) | 2019.09.24 |
setvbuf(3) - stream buffering 방식을 지정함 (0) | 2019.09.24 |