CS(computer science)

[linux 뽀개기] - tcgetattr - 터미널 정보를 저장하는 함수 , ECHOCTL

ebang 2023. 1. 3. 23:00
반응형

[담고 있는 내용]

1. tcgetattr 함수란 

2. 함수가 저장하는 terminos 구조체란

3. terminos 구조체 내의 flag 중에서도 c_lflag

4. c_lflag 옵션중에서도 ECHOCTL

 

 

1. tcrgetattr 함수

NAME

tcgetattr - get the parameters associated with the terminal

SYNOPSIS

#include <termios.h>int tcgetattr(int fildes, struct termios *termios_p);

DESCRIPTION

The tcgetattr() function shall get the parameters associated with the terminal referred to by fildes and store them in the termios structure referenced by termios_p. The fildes argument is an open file descriptor associated with a terminal.

The termios_p argument is a pointer to a termios structure.

The tcgetattr() operation is allowed from any process.

If the terminal device supports different input and output baud rates, the baud rates stored in the termios structure returned by tcgetattr() shall reflect the actual baud rates, even if they are equal. If differing baud rates are not supported, the rate returned as the output baud rate shall be the actual baud rate. If the terminal device does not support split baud rates, the input baud rate stored in the termios structure shall be the output rate (as one of the symbolic values).

RETURN VALUE

Upon successful completion, 0 shall be returned. Otherwise, -1 shall be returned and errno set to indicate the error.



 

[해석]

terminos_p 포인터가 가리키는 terminos 구조체에 정보를 저장한다.

flides : terminal에서 열려있는 file desctriptor.

baud rate - 다르게 할 수 있다면 input, outputd의 서로 다른 실제 baud rate를 저장한다.

그렇지 않다면 output rate으로만 저장.

 

성공 시 0을 반환, 실패시 -1을 반환하면서 errno가 set된다. 

 

 💡Baud rate란?
는 초당 데이터 비트(0 or 1)를 얼마만큼 전송할 수 있는지 나타내는 값. BPS(Bit Per Second)로도 나타냄.
PCIe나 버스의 데이터 전송 속도를 나타낼 때 주로 사용

2. terminos 구조체

💡 terminos 구조체

struct termios { 
tcflag_t c_iflag; /* input flags - input 과 관련 / 
tcflag_t c_oflag; / output flags - output과 관련 /
tcflag_t c_cflag; / control flags  - 제어 문자 관련/
tcflag_t c_lflag; / local flags  - local flag 관련/ 
cc_t c_cc[NCCS]; / control chars  - 제어 문자 저장/
speed_t c_ispeed; / input speed  - input baud_rate/
speed_t c_ospeed; / output speed  output baud_rate */ 
};

 

3. terminos 구조체 내의 c_lflag 

여기서 주목해서 볼 flag는 c_lflag 이다. (local flags)

 

c_lflag가 가질 수 있는 옵션들 중 일부는 다음과 같다.

 

ICANON - Perhaps the most important bit in c_lflag is the ICANON bit. Enabling it enables “canonical” mode – also known as “line editing” mode. When ICANON is set, the terminal buffers a line at a time, and enables line editing. Without ICANON, input is made available to programs immediately (this is also known as “cbreak” mode).

ECHO in c_lflag controls whether input is immediately re-echoed as output. It is independent of ICANON, although they are often turned on and off together. When passwd prompts for your password, your terminal is in canonical mode, but ECHO is disabled.

ISIG in c_lflag controls whether ^C and ^Z (and friends) generate signals or not. When unset, they are passed directly through as characters, without generating signals to the application.

 

[해석]

c_lflag는 unsigned long 형으로, 여러가지 비트들의 값이 여러 플래그들의 On, off를 의미한다.

ICANON - 가장 중요한 비트. 'canonical mode' 진입이 가능하게 끔한다. 이 플래그가 켜져있으면 한번에 한 줄을 버퍼로 만들어서 line editing이 가능해지게 한다. 이 설정이 꺼져 있으면 'cbreak'모드라고 해서 프로그램에 input이 즉시 입력된다. 

 

ECHO - input이 output으로 그대로 반향되게끔 할 것인지의 설정을 할 수 있다. 

 

ISIG - ^C, ^Z 와 같은 문자들이 signal을 생성하게끔 할지, 아닐지 설정하게 할 수 있다. 만약 설정이 꺼져있다면 제어문자로서 기능하지 않고 그냥 문자로 해석된다. 

 

4. c_lflag 중에서 ECHOCTL

 

ECHOCTL - ECHO처럼 입력이 반향되는 것인데, ctl 즉 제어문자만을 반향하는 것이다.  ^x, ^c, 등등이 있다. 

 

ECHOCTL의 원래 기능, 원래 사용

ECHOCTL (not in POSIX)

If ECHO is also set, terminal special characters other than TAB, NL, START, and STOP 
are echoed as ^X, where X is the character with ASCII code 0x40 greater than 
the special character. For example, character 0x08 (BS) is echoed as ^H. 
[requires _BSD_SOURCE or _SVID_SOURCE]


->  말그대로 'echo ctrl'  : 제어문자 출력 이라는 뜻으로, 제어문자 출력을 하기 위한 설정 비트 값이다!

 

*c_flag들은 그 설정값들을 설정하기 위해서 각 플래그와 비트 연산을 한다. 

-c_lflag 에서 ECHOCTL flag를 끄기 위해서는,  c_flag 와 (~ECHOCTL)을 AND 연산하면 된다. 

			[구조체].c_lflag &= (~ECHOCTL);

 

 

참고)관련된 실습들

stty -ctlecho

terminal 설정 - 모든 입력을 출력한다.

취소 : man stty | less +/ctlechotcgetattr

 

<echoctl 켜고 끄기>

stty -echoctl # turn echoctl off
stty echoctl  # turn echoctl on

 

 

 

<echoctl 을 껐을 때와 켰을 때>

sleep 3600 or cat > /dev/null

둘 중 하나의 명령어를 치고

		esc + [41m foo<Enter>

를 쳐보자. 

 

그러면

^[41m foo

가 출력되는 걸 볼 수 있다. 

sleep 하는 중에 esc키를 눌렀기 때문에, signal을 받아서 (esc키는 ctrl + [ 와 같은 signal을 보낸다. 그래서 ^[가 출력되는 것.)

 

 

그런데 echoctl이 꺼져있다면, 

다시 위의 처럼 키를 눌러보았을 때 는 ^문자가 보이지 않고 

이러한 출력이 보인다. 

 

 

  esc를 제어문자로 해석하지 않고 터미널에서 [41m  입력된 값을 해석해서 설정을 변경하는 것이다. 

그다음 터미널에 foo를 입력할 때 신기하게도 글자 배경이 붉은색으로 변경되는 것이다! 

 

 

[정리]

terminos 내 구조체의 c_lflag는 ECHOCTL, ECHO 등의 flag를 가질 수 있는 flag로 

실제 터미널 사용자에게 보여지는 터미널 속성 즉 출력의 반향(ECHO)을 on/off 하거나 특수입력 문자들 (ctrl + c 와 같은) 속성제어를 하기 위해 사용한다 .

그 중 하나인 ECHOCTL은 제어 문자를 출력할 것이냐, 말것이냐와 관련된 비트이고,

실제 signal을 무시할 것인가 아니면 그 signal에 따른 service routine을 실행할 것인가는 관련이 없으며 오히려 c_lflag 와 관련이 있다. (아마도 c_lflag 의 ISIG)

 

 

 

[사용]

리눅스 쉘에서 myshell, minishell 즉 나만의 쉘을 만들고자 할 때, signal이 들어오면 전체 쉘이 종료되면 문제가 될 수 있다. 

따라서 제어문자가 들어올 때 그것을 출력하지 않도록 하고(ECHOCTL) signal을 무시하도록 하는 것(sigaction 사용)에 이 속성들을 사용할 수 있다. 

 

 

 

 

 

 

 

- 본 게시물은 주관적인 구글링, 해석이 들어갔기 때문에, 지극히 개인적인 게시물입니다. 

 

 

반응형