[제5장] 터미널
=================================================================
* Subject : [제5장] 터미널
* Writer: w0rm9 (research.hackerschool.org)
* Date: 2004/01/25
=================================================================
/* 스터디했던 내용을 중심으로 그 때 사용한 소스를 바탕으로 정리했습니다.
* 스터디 한지 오래되서 기억이 가물가물하네요. :)
*/
0x01. 터미널로부터 읽기 기록하기
■ isatty
사용법)
#include <unistd.h>
int isatty(int fd);
=> 파일 기술자가 현재 터미널과 연결되어 있는지 확인함. 연결되면 1, 그렇지 않으면 0을 반환
테스트)
[w0rm9@work TERM]$ cat isatty.c
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
int main()
{
int fd;
fd = open("babo.c", O_RDONLY);
if(!isatty(fd)){
fprintf(stderr, "you are not a terminal\n");
exit(1);
}
}
[w0rm9@work TERM]$ gcc -o isatty isatty.c
[w0rm9@work TERM]$ ./isatty
you are not a terminal
■ 터미널과 대화하기
사용법)
dev/tty를 통해 직접 터미널에 전송할 경우 사용자가 리다이렉트를 이용해서 그 메시지 출력을 무시할 수 없다.
테스트)
[w0rm9@work TERM]$ cat tty.c
#include <stdio.h>
#include <unistd.h>
int main() {
FILE *output;
output = fopen("/dev/tty","w");
if(!output) {
fprintf(stderr,"cannot open /dev/tty\n");
exit(1);
}
fwrite("babo w0rm9\n", 12, 1, output);
sleep(3);
printf("fwrite..done\n");
}
[w0rm9@work TERM]$ gcc -o tty tty.c
[w0rm9@work TERM]$ ./tty
babo w0rm9
fwrite..done
[w0rm9@work TERM]$ ./tty > file
babo w0rm9
[w0rm9@work TERM]$ cat file
fwrite..done
0x02. termios 구조체
#include <termios.h>
struct termios {
tcflag_t c_iflag;
tcflag_t c_oflag;
tcflag_t c_cflag;
tcflag_t c_lflag;
cc_t c_cc[NCCS];
};
■ tcgetattr, tcsetattr
사용법)
#include <termios.h>
int tcgetattr(int fd, struct termios *termios_p);
int tcsetattr(int fd, int actions, const struct termios *termios_p);
=> tcgetattr을 호출하면 termios_p가 가리키는 구조체 내에 터미널 인터페이스 변수의 현재 값을 저장한다.
tcsetattr을 호출하면 터미널 인터페이스를 다시 환경 설정할 수 있다.
□ actions : 변경이 적용되는 방법
TCSANOW 값을 즉시 변경한다.
TCSADRAIN 현재 출력이 완료될 때 값을 변경한다.
TCSAFLUSH 현재 출력이 완료될 때 값을 변경하지만, 현재 유효하거나 read 호출에서 아직까지 반환되지 않은 입력을 버린다.
테스트)
[w0rm9@work TERM]$ cat pass.c
#include <termios.h>
#include <stdio.h>
#define PASSWORD_LEN 8
int main() {
struct termios initial, newsetting;
char password[PASSWORD_LEN+1];
tcgetattr(fileno(stdin), &initial);
newsetting = initial;
newsetting.c_lflag &= ~ECHO;
printf("Enter password: ");
if(tcsetattr(fileno(stdin), TCSAFLUSH, &newsetting) != 0) {
fprintf(stderr, "Could not set att\n");
}
else {
fgets(password, PASSWORD_LEN, stdin);
tcsetattr(fileno(stdin), TCSANOW, &initial); //fileno: 인자로 주어진 스트림에서 정수 형태의 디스크립터 값을 빼오는 함수
fprintf(stdout, "\nYou entered %s\n", password);
}
exit(0);
}
[w0rm9@work TERM]$ gcc -o pass pass.c
[w0rm9@work TERM]$ ./pass
Enter password:
You entered babo
0x03. terminfo 기능 사용하기
■ setupterm
사용법)
#include <term.h>
int setupterm(char *term, int fd, int *errret);
=> 현재 터미널 형태를 파라미터 term에 지정된 것으로 설정한다.
테스트)
[w0rm9@work TERM]$ cat terminfo.c
#include <stdio.h>
#include <term.h>
#include <ncurses.h>
int main() {
int nrows, ncols;
setupterm(NULL, fileno(stdout), (int *)0);
nrows = tigetnum("lines"); //tigetnum: 숫자형 값 반환
ncols = tigetnum("cols");
printf("%d cols, %d rows\n",ncols, nrows);
exit(0);
}
[w0rm9@work TERM]$ gcc -o terminfo terminfo.c -I/usr/include/ncurses -lncurses
[w0rm9@work TERM]$ ./terminfo
132 cols, 49 rows
0x04. 키 입력 감지하기
p.265 참고-_- 알아서 테스트해볼 것
_eof_
