#include <termios.h>
struct termios
{
tcflag_t c_iflag; /* input modes */
tcflag_t c_oflag; /* output modes */
tcflag_t c_cflag; /* control modes */
tcflag_t c_lflag; /* local modes */
cc_t c_cc[NCCS]; /* control chars */
}
- termios 구조체
- POSIX가 지정하는 표준 인터페이스
- 시스템 V 인터페이스 termio와 비슷하다.
- termios 형식의 구조체에 값을 설정함으로써 인터페이스 제어
- termios.h에 정의되어 있다.
- 5가지 모드(입력, 출력, 제어, 로컬, 특수 제어 문자)로 분류 가능
- int tcgetattr(int fd, struct termios *termios_p);
- termios 구조체 초기화
- 터미널 인터페이스 변수의 현재 값을 termios_p가 가리키는 구조체에 기록한다.
- int tcsetattr(int fd, int action, const struct termios *terios_p);
- 터미털 인터페이스 변수의 값을 변경하였다면 tcsetattr 함수로 다시 설정해야 한다.
- action 필드는 이후의 변화를 어떻게 적용시킬 것인지를 제어한다.
- TCSANOW : 값을 즉시 변경한다.
- TCSADRAIN : 현재 출력이 완료되었을 때 값을 변경한다.
- TCSAFLUSH : 현재 출력이 완료되었을 때 값을 변경한다. 그러나 현재 유효한 입력이나 read 호출에서 아직 리턴되지 않은 입력은 취소한다.
- 프로그램에서 프로그램이 시작하기 전의 값으로 터미널 설정 값을 복구하는 것은 매우 중요하다. 항상 프로그램을 시작할 때 터미널의 값을 저장하고 끝낼 때 그것을 복구해야 한다.
- 입력 모드
입력이 프로그램에 전달되기 전에 어떻게 처리되어야 하는지를 제어한다. termios 구조체의 c_iflag 멤버의 플래그를 설정하여 입력 모드를 제어한다. 입력 모드는 기본 값이 가장 많이 사용되고 아주 특별한 경우가 아니면 변환할 일이 없다.- BRKINT : 라인에서 break 조건이 감지되면 인터럽트를 발생한다.
- IGNBRK : 라인에서 break 조건을 무시한다.
- ICRNL : 입력된 CR을 NL으로 반환한다.
- INLCR : 입력된 NL을 CR으로 반환한다.
- IGNPAR : 입력된 문자 중 패리티 에러가 있는 문자는 무시한다.
- INPCK : 입력 문자들에 패리티 에러가 있는 문자는 무시한다.
- PARMRK : 패리티 에러를 표시한다.
- ISTRP : 입력되는 모든 문자들을 7비트로 벗긴다.
- IXOFF : 입력시에 소프트웨어 흐름 제어를 가능하게 한다.
- IXON : 출력시에 소프트웨어 흐름 제어를 가능하게 한다.
==> BRKINT나 IGNBRK 둘 다 설정되지 않았다면 라인에서 break 조건은 NULL(0x00) 문자로 읽힌다.
- 출력 모드
프로그램에서 받은 문자들을 시리얼 포트나 화면에 내보내기 이전에 출력 문자들을 어떻게 처리할 것인지를 제어한다. termios 구조체의 c_oflag 멤버에 플래그를 설정하여 출력 모드를 제어한다.- OPOST : 출력시 처리를 한다.
- ONLCR : 출력시 NL을 CR과 NL로 반환한다.
- OCRNL : 출력시 CR을 NL으로 반환한다.
- ONLRET : NL을 CR으로 취급한다.
- ONOCR : column 0에서 CR을 출력하지 않는다.
- OFILL : 지연하기 위해서 채움 문자를 보낸다.
- OFDEL : 채움 문자로 NULL 대신 DEL을 사용한다.
- NLDLY : NL 지연 선택
- CRDLY : CR 지연 선택
- TABDLY : TAB 지연 선택
- BSDLY : BS 지연 선택
- VTDLY : 수직 TAB 지연 선택
- FFDLY : FORM FEED 지연 선택
==> OPSOT가 설정되어 있지 않다면 다른 모든 플래그들은 무시된다.
- 제어 모드
터미널의 하드웨어 특성을 제어한다. termios 구조체의 c_cflag 멤버의 플래그를 설정하여 제어 모드를 지정한다. 주로 직렬 회선이 모뎀에 연결되는 경우에 사용한다. 자주 쓰이지 않는다.- CLOCAL : 모뎀 상태 라인을 무시한다. (Ignore modem status lines.)
- CREAD : 문자 수신을 가능하게 한다. (Enable Receiver.)
- CS5 : 문자를 보내거나 받을 때 5비트를 사용한다.
- CS6 : 문자를 보내거나 받을 때 6비트를 사용한다.
- CS7 : 문자를 보내거나 받을 때 7비트를 사용한다.
- CS8 : 문자를 보내거나 받을 때 8비트를 사용한다.
- CSTOPB : 한 문자당 2개의 정지 비트를 사용한다.
- HUPCL : 모뎀을 끊는다.
- PARENB : 패리티 발생과 검사를 가능하게 한다.
- PARODD : 홀수 패리티를 사용한다.
==> HUPCL이 설정되어 있다면 터미널 드라이버가 터미널을 참조하는 마지막 파일 기술자가 닫혀 있을 때 모뎀 제어 라인을 라인이 끊기도록(hang-up) 설정한다.
- 로컬 모드
터미널의 다양한 특성을 제어한다. termios 구조체의 c_lflag 멤버의 플래그를 설정하여 로컬 모드를 지정한다.- ECHO : 입력되는 문자의 로컬 echo를 가능하게 한다.
- ECHOE : ERASE 문자를 받게 되면 BS, SP, BS를 수행한다.
- ECHOK : KILL 문자를 받게 되면 라인을 지운다.
- ECHONL : NL 문자를 echo한다.
- ICANON : 정규 입력 처리(canonical input)를 가능하게 한다.
- IEXTEN : 입력 처리시에 특별하게 정의한 함수를 사용 가능하게 한다.
- IESIG : 시그널을 가능하게 한다.
- NOFLSH : 큐를 FLUSH하지 않도록 한다.
- TOSTOP : 쓰기 시도시에 백그라운드 프로세스에게 시그널을 보낸다.
==> 여기에서 두 가지 중요한 플래그는 ECHO와 ICANON이다. ECHO를 사용하면 입력되는 문자를 출력하지 않을 수도 있다. ICANON은 터미널에서 입력 받는 문자를 처리할 때 서로 상이한 두 가지 모드 사이를 왔다 갔다 할 수 있다. ICANON이 설정되었다면 라인은 정규 모드가 되고, 설정되지 않았다면 비정규 모드가 된다.
- 특수 제어 문자
Ctrl+C와 같은 특수한 방법으로 사용하는 문자들의 모임이다. termios 구조체의 c_cc 배열 멤버는 지원 가능한 기능에 대응되는 문자들을 포함하고 있다.- 정규 모드(canonical)에서 배열 인덱스는 다음과 같다.
- VEOF : EOF 문자
- VEOL : EOL 문자
- VERASE : ERASE 문자
- VINTR : INTR 문자
- VKILL : KILL 문자
- VQUIT : QUIT 문자
- VSUSP : SUSP 문자
- VSTART : START 문자
- VSTOP : STOP 문자
- 비정규 모드(non-canonical)에서 배열의 인덱스는 다음과 같다.
- VINTR : INTR 문자
- VMIN : MIN 문자
- VQUIT : SUSP 문자
- VTIME : TIME 문자
- VSTART : START 문자
- VSTOP : STOP 문자
- 특수 문자와 비정규 모드에서의 MIN과 TIME은 입력 문자를 발전적으로 처리하는데 있어서 매우 중요하다.
- TIME과 MIN 값
비정규 모드에서 사용되고 입력으로부터 읽어 들이기를 제어하는데 함께 사용된다. 프로그램이 터미널과 연관된 파일 기술자로부터 읽기를 시도할 때 일어나는 사건을 제어한다.- MIN=0이고 TIME=0 : read는 항상 즉시 리턴한다.
- MIN=0이고 TIME>0 : read는 읽어들일 문자가 있거나 TIME/10초가 경과했을 때 리턴한다.
- MIN>0이고 TIME=0 : read는 MIN개의 문자를 읽을 때까지 기다릴 것이고, 읽어들인 문자의 개수를 리턴할 것이다. 파일의 끝이라면 0을 리턴한다.
- MIN>0이고 TIME>0 : read가 호출되었을 때 읽어들일 문자를 기다린다. 첫 번째 문자가 도착하면 이제 타이머가 작동한다. read는 MIN개의 문자를 읽어들였거나 타이머가 TIME/10초 만큼 경과했을 때에 리턴할 것이다.
- 정규 모드(canonical)에서 배열 인덱스는 다음과 같다.
- 명령행에서 터미널 모드 설정하기
- 자신의 터미널 형태를 식별하기
- $ echo $TERM
- 터미널의 현재 설정 값을 보여준다.
- $ stty -a
- 쉘 스크립트가 한 번에 한 문자씩 처리하도록 하려면 MIN을 1로 설정하고 TIME을 0으로 설정하여 정규 모드를 꺼야 한다.
- $ stty -icanon min 1 time 0
- echo 끄기
- $ stty -echo
- echo 다시 켜기
- $ stty echo
- 자신의 터미널 형태를 식별하기
[출처] https://m.blog.naver.com/eom913/142426722
Linux TTY 플래그