티스토리 뷰

전부터 계속 하고 싶다가 방법을 못 찾아서 포기 했었는데, 드디어 알아냈습니다.

library를 쓰다 보면, 라이브러리에서 에러 상황에서 fprintf(stderr, ...)을 쓰거나, printf를 쓰는 상황이 있습니다.

프로그램을 shell로 직접 실행하는 경우에는 print되는 내용을 모두 확인할 수 있지만,
fork되어 실행되거나, systemd에 의해 실행되는 등의 상황에서는 내용 확인이 안되어 답답할 수 있습니다. (최소한 저의 경우는요 ^^;;)

우연히 pulseaudio 코드를 보다가 발견했습니다.
오픈소스의 긍정적인 측면이 아닌가 싶습니다. (pulseaudio 개발자들 고마워요)


unistd.h 헤더를 열어보면, 다음과 같은 표준 파일 descriptor의 define을 확인할 수 있습니다.
다음 descriptor들은 각각 FILE * stdin / stdout / stderr 에 해당하는 descriptor 형태입니다.

/* Standard file descriptors.  */
#define STDIN_FILENO    0   /* Standard input.  */
#define STDOUT_FILENO   1   /* Standard output.  */
#define STDERR_FILENO   2   /* Standard error output.  */


또한, unistd.h 에는 dup2라는 함수가 존재합니다.

/* Duplicate FD to FD2, closing FD2 and making it open on the same file.  */
extern int dup2 (int __fd, int __fd2) __THROW;

첫 번째 인자의 fd1을 두번째 인자의 fd2에 복사할 수 있습니다.
fd1이 가리키는 실제 file 또는 논리적 어떤 것을 fd2의 값에도 연결 시키는 개념이 되겠습니다.
이후에는 fd2에 read/write 하더라고 fd1을 사용한 것과 같은 결과를 가지게 됩니다.

이에 따라 파일을 하나 open 한 뒤 이때 생긴 fd를 stderr이나 stdout으로 dup2 하면,
fprintf(stderr, ...) 등으로 print된 내용을 내가 원하는 파일에 write 시킬 수 있습니다.


다음과 같이 작성할 경우, stderr로 printf된 내용을 test.txt 에서 확인할 수 있습니다.

fd = open("test.txt", O_WRONLY|O_CREAT, 0644);
dup2(fd, STDERR_FILENO);
//dup2(fd, STDOUT_FILENO);
fprintf(stderr, "test string\n");

응용하자면, socket을 열고 selector나 main loop으로 받아서 자신이 사용하는
log system으로 redirection 시켜도 좋을 듯 합니다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함