터미널 출력 제어를 위한 termios 구조체 이해하기

지난 글에서 설명했듯이 OS X, 리눅스를 포함한 Unix를 이어받은 운영 체제는 LF(line feed, 0x0A, \n)를 개행 문자, 즉 커서를 다음 줄의 시작으로 옮기는 문자로 이용한다. 하지만 표준에 정의 된 LF의 동작은 커서를 다음 줄로 내리는 것일 뿐, 커서를 줄의 처음으로 이동하지 않는다. 파일을 항상 운영 체제에 종속적인 애플리케이션을 통해서만 접근한다면 표준과 다른 동작은 문제되지 않는다. 하지만 파일과 입출력의 구분이 없는 유닉스 계열에서 파일과 프로세스의 입출력이 상호작용할 때 이 차이는 문제될 수 있다.

이 차이를 다루기 위해서 터미널은 출력에 적절한 가공을 하여 출력한다. 이를 제어하기 위한 플래그가 POSIX.1 표준이 정의 하는 termios 구조체의 c_oflag다. c_oflag는 터미널이 받은 문자를 출력하기 전에 어떤 후처리를 할지에 대한 플래그다.

c_oflag에서 가장 중요한 플래그는 OPOST다. 이는 입력에 대한 후처리를 할지 말지에 대한 플래그로 OPOST가 꺼져있으면 다른 플래그와 상관없이 터미널은 받은 문자열을 그대로 보여준다. 이 플래그를 끄는 경우는 거의 없다. 하지만 터미널을 텍스트를 보여주기 위한 용도가 아닌 바이너리 데이터를 전송하기 위해 사용하는 경우 끄는 것이 좋다.

터미널이 Unix 계열 운영 체제에서 원하는대로 동작할 수 있게 해주는 플래그는 ONLCR이다. ONLCR이 켜져 있으면 터미널은 출력을 해석할 때 NLCRNL로 해석한다. 즉, Unix에서도 ONLCR이 꺼져있다면, LF를 만났을 때, 다음 줄의 처음으로 이동하는 것이 아닌, 현재 위치의 다음 줄로 이동한다. Unix 계열 운영 체제에서 윈도우에서 만들어진 파일을 출력해야 할 경우, CRNLNL로 바꾸지 않고도 ONLCR 플래그를 끄는 것 만으로도 간단하게 출력할 수 있다.

이외에도 구형 Mac OS 처럼 동작하게 해주는 OCRNL 플래그나 탭문자(0x09, \t)를 크기에 맞는 스페이스로 바꿔주는 XTABS 플래그 등 다양한 플래그들이 존재한다. 이런 플래그들을 통해 개발자는 터미널 출력에 대한 세밀한 제어를 할 수 있고, 터미널 기반 애플리케이션을 개발할 때 운영 체제간의 차이를 무시하고 동작을 통일할 수 있다.

댓글

이 블로그의 인기 게시물

Escape Codes의 역사

[C++] enum class - 안전하고 쓰기 쉬운 enum

RAII는 무엇인가

Log Aggregator 비교 - Scribe, Flume, Fluentd, logstash

[Python] cache 데코레이터로 최적화하기