713 words
4 minutes
setvbuf()
CTF나 Wargame에서 setvbuf()
가 다음과 같이 설정되어 있는 경우를 자주 볼 수 있습니다.
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
이번 포스팅에서는 왜 setvbuf()
설정이 필요한지 자세히 알아보겠습니다.
setvbuf()
setvbuf()
는 C 언어 표준 라이브러리 함수 중 하나로, 스트림의 버퍼링 및 버퍼 크기를 제어합니다.
setvbuf()
의 구성을 보면 다음과 같습니다.
int setvbuf(FILE *stream, char *buffer, int mode, size_t size);
stream
: 버퍼링 모드를 변경할 대상 스트림을 지정합니다. 보통stdin
,stdout
,stderr
같은 표준 스트림이나 파일을 열 때 얻은 포인터가 사용됩니다.buffer
: 사용자가 할당한 버퍼입니다. 만약NULL
을 전달하면 내부적으로 자동으로 버퍼가 할당되거나 지정된 모드에 따라 버퍼링을 제어합니다.mode
: 스트림의 버퍼링 방식을 지정하는 상수를 넣습니다. 주로 사용되는 모드는 다음과 같습니다._IOFBF
(0): 버퍼가 꽉 차면 자동으로 플러시1되어 데이터가 출력되거나, 명시적으로 플러시할 때 데이터가 출력됩니다._IOLBF
(1): 줄 단위 버퍼링으로, 개행 문자(\n
)가 입력되면 버퍼가 플러시됩니다._IONBF
(2): 버퍼링을 사용하지 않고, 입출력 명령이 호출되면 즉시 데이터를 처리합니다.
size
: 버퍼 크기(바이트)입니다. 버퍼링 모드(_IONBF
)인 경우에는 이 값이 의미가 없으므로 보통 0을 전달합니다.- 반환값: 정상 실행 시 0을 반환하고, 오류가 발생하면 0이 아닌 값이 반환됩니다.
setvbuf()의 필요성
앞서 setvbuf()
에 대해 자세히 살펴보았습니다. 그렇다면 왜 CTF나 Wargame에서는 이 함수를 설정할까요? 그 이유는 프로그램이 데이터를 즉시 읽고 출력할 수 있도록 하여 입출력 지연을 제거하기 위함입니다. 만약 setvbuf()
를 사용하지 않는다면, 중요한 메시지가 버퍼에 쌓여 제때 출력되지 않아 사용자에게 불편을 줄 수 있습니다.
Conclusion
이처럼 setvbuf()
는 프로그램이 데이터를 즉시 처리할 수 있도록 함으로써 버퍼링으로 인한 출력 지연 문제를 해결해줍니다. 특히 CTF나 Wargame과 같이 실시간 상호작용이 요구되는 환경에서는 버퍼링으로 인해 중요한 메시지가 늦게 출력되는 것을 방지하는 데 큰 도움이 됩니다.
References
Footnotes
플러시(flush): 버퍼에 저장된 데이터를 강제로 출력 대상으로 보내는 작업 ↩