-
[SW 정글 50일차] stdout 와 STDOUT_FILENO (feat. File Descriptor)기타/SW 사관학교 정글 2021. 9. 21. 01:57
stdout는 C 언어의 표준 I / O 스트림에 속하는 것으로 type이 FILE *이고 stdio.h에 정의되어 있다.
STDOUT_FILENO는 LINUX 시스템의 파일 디스크립터로 type이 int이고 unistd.h에 정의되어 있다.unistd.h에서를 보면 아래와 같다.
The following symbolic constants shall be defined for file streams:
STDIN_FILENO File number of stdin; 0.
STDOUT_FILENO File number of stdout; 1.
STDERR_FILENO File number of stderr; 2.둘의 차이를 알아보기 전에 새로 접한 개념인 파일 디스크립터에 대해 알아보자.
파일 디스크립터(File Descriptor)는 시스템으로부터 할당 받은 파일을 대표하는 0이 아닌 정수 값으로 프로세스에서 열린 파일의 목록을 관리하는 테이블의 인덱스이다.
더보기커널은 각 프로세스별로 open file descriptor table을 갖고 있다.
테이블의 각 엔트리는 하나의 파일 디스크립터에 대한 동작 제어 플래그, 열린 파일을 가리키는 참조를 담고 있다.
open file description은 현재 파일의 offset, flag, 접근 모드, i/o 관련 설정, 파일의 i-node 객체를 가리키는 레퍼런스를 갖고 있다.
i-node는 파일 종류 (일반파일, 소켓, fifo)와 권한, lock 목록 포인터, 여러 파일 오퍼레이션과 다양한 파일 속성(크기, 타임스탬프등)을 갖고 있다.
같은 open file description을 가리키는 2개의 fd는 offset값을 공유 한다.
유닉스 시스템에서는 모든 것은 파일이라고 하는데 일반적인 정규파일부터 디렉토리, 소켓, 파이프, 블록 디바이스, 케릭터 디바이스 등 모든 객체들을 파일로 관리한다.
파일의 종류에 대한 자세한 정보는 아래의 블로그를 확인하면 좋을 것같다.
https://hippogrammer.tistory.com/82
파일 디스크립터는 파이프, FIFO, 소켓, 터미널, 디바이스, 일반파일 등 종류에 상관없이 모든 열려있는 파일을 참조할때 쓴다.
프로세스가 실행 중에 파일을 Open하면 커널은 해당 프로세스의 파일 디스크립터 숫자 중 사용하지 않는 가장 작은 값을 할당해준다.
그 다음에 프로세스가 열려있는 파일에 시스템 콜을 이용해서 접근할 때, 파일 디스크립터(FD)값을 이용해서 파일을 지칭할 수 있다.
프로그램이 프로세스로 메모리에서 실행될 때, 기본적으로 할당되는 파일디스크립터는 표준입력(Standard Input), 표준 출력(Standard Output), 표준에러(Standard Error)이며 이들에게 각각 0, 1, 2라는 정수가 할당된다.
그러면 이제 stdout과 STDOUT_FILENO의 차이점에 대해 알아보자.
먼저, 무엇을 의미하고 있는지 아래의 표로 확인해보자.
STDOUT_FILENO와 stdout은 둘 다 파일디스크립터 1을 가리키고 표준 출력을 위해 사용된다.
기본적으로 표준 입력은 키보드에서 읽고 표준 출력 및 표준 오류는 화면에 출력된다.
일단은 가장 큰 차이점은 STDOUT_FILENO는 unistd.h에 속한 POSIX 이름으로 1이라는 것을 가리키는 int형이다.
stdout은 stdio.h에 속한 stdio 스트림으로 파일을 가리키는 FILE 포인터형이다.
stdout은 constant이므로 새로운 값을 할당할 수없다는 것이 특징이다.
하지만, freopen함수를 사용하여 스트림을 디스크 파일 또는 다른 디바이스로 리디렉션할 수 있고 운영 체제에서는 명령 수준에서 프로그램의 표준 입력 및 출력을 리디렉션할 수 있다.
STDOUT_FILENO는 write systemcall을 사용하고자 할 때 쓰이는 기본적으로 할당되는 파일디스크립터인 표준 출력인 1을 가지고 있는 것이다.
이둘의 차이점은 겉으로 봤을 때는 이렇고 사실 상 비슷한 개념이여서 내부적인 차이점을 찾기는 힘들다.
실제로 둘의 관계는 STDOUT_FILENO == fileno(stdout)이다.
[오늘의 나는 어땠을까?]
오늘은 어제부터 작성한 Tiny 웹서버 구현 코드를 다시보며 놓쳤던 것은 없는지, 다시 봤는데 기억이 잘 나지 않는 부분을 복습했다.
이번에 주어진 시간이 많아 뭔가 더 해보려고 했는데 일단은 주어진 과제를 완벽하게 나의 것으로 만드는 것을 목표로 하고 시간이 남으면 더 공부해보고 싶었던 것이나 복습을 하려고 한다.
지금 내게 주어진 것도 제대로 하지 않고 새로운 것을 하는 것은 무리인 것같다.
오늘은 저녁을 밖에서 먹고 들어왔는데 약 1시간 30분정도를 저녁식사에 시간을 썼다.
돌아오면서 생각해보니 너무 많은 시간을 쓴다고 생각해서 되도록이면 학식을 먹어야겠다는 생각을 가졌다.
식사시간을 적어도 30분 정도만 줄였어도 코딩테스트 1문제를 더 봤을 수도 있다.
내게 주어진 모든 시간들은 귀하고 다시 돌릴 수 없기 때문에 정말 효율적으로 써야하고 그러고 싶다.
<참고 자료>
https://dev-ahn.tistory.com/96
'기타 > SW 사관학교 정글' 카테고리의 다른 글
[SW 정글 51일차] MIME 타입, CGI, datagram vs stream (0) 2021.09.22 [SW 정글 추석 특집] Missing Semester 2일차 (0) 2021.09.21 [SW 정글 49일차] Tiny 웹 서버 구현하기 (1) 2021.09.20 [SW 정글 추석 특집] Missing Semester 1일차 (0) 2021.09.19 [SW 정글 48일차] 소켓 인터페이스 구현부터 Echo 클라이언트와 서버까지 (0) 2021.09.19