코드
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define FALSE 0
#define TRUE 1
//volatile int STOP=FALSE;
void ft_bitprintf(unsigned long data, int index)
{
unsigned long bit;
bit = data;
if (index)
ft_bitprintf(data >> 1, index - 1);
printf("%ld ", bit % 2);
}
void ft_terminal_printf(struct termios tty)
{
//https://www.thinkage.ca/gcos/expl/c/lib/printf.html
printf("================ struct termios ================\n");
printf("%20s\t%10lu\t", "tty.c_iflag", tty.c_iflag);
ft_bitprintf(tty.c_iflag, 32);
printf("\n");
printf("%20s\t%10lu\t", "tty.c_oflag", tty.c_oflag);
ft_bitprintf(tty.c_oflag, 32);
printf("\n");
printf("%20s\t%10lu\t", "tty.c_cflag", tty.c_cflag);
ft_bitprintf(tty.c_cflag, 32);
printf("\n");
printf("%20s\t%10lu\t", "tty.c_lflag", tty.c_lflag);
ft_bitprintf(tty.c_lflag, 32);
printf("\n");
printf("%20s\t%10lu\n", "tty.c_ispeed", tty.c_ispeed);
printf("%20s\t%10lu\n", "tty.c_ospeed", tty.c_ospeed);
printf("\n============== c_cc ==================\n");
printf("%20s\t%d\n", "tty.c_cc[VEOF]", tty.c_cc[VEOF]);
printf("%20s\t%d\n", "tty.c_cc[VEOL]", tty.c_cc[VEOL]);
printf("%20s\t%d\n", "tty.c_cc[VEOL2]", tty.c_cc[VEOL2]);
printf("%20s\t%d\n", "tty.c_cc[VERASE]", tty.c_cc[VERASE]);
printf("%20s\t%d\n", "tty.c_cc[VWERASE]", tty.c_cc[VWERASE]);
printf("%20s\t%d\n", "tty.c_cc[VKILL]", tty.c_cc[VKILL]);
printf("%20s\t%d\n", "tty.c_cc[VREPRINT]", tty.c_cc[VREPRINT]);
printf("%20s\t%d\n", "tty.c_cc[VINTR]", tty.c_cc[VINTR]);
printf("%20s\t%d\n", "tty.c_cc[VQUIT]", tty.c_cc[VQUIT]);
printf("%20s\t%d\n", "tty.c_cc[VSUSP]", tty.c_cc[VSUSP]);
printf("%20s\t%d\n", "tty.c_cc[VDSUSP]", tty.c_cc[VDSUSP]);
printf("%20s\t%d\n", "tty.c_cc[VSTART]", tty.c_cc[VSTART]);
printf("%20s\t%d\n", "tty.c_cc[VSTOP]", tty.c_cc[VSTOP]);
printf("%20s\t%d\n", "tty.c_cc[VLNEXT]", tty.c_cc[VLNEXT]);
printf("%20s\t%d\n", "tty.c_cc[VDISCARD]", tty.c_cc[VDISCARD]);
printf("%20s\t%d\n", "tty.c_cc[VMIN]", tty.c_cc[VMIN]);
printf("%20s\t%d\n", "tty.c_cc[VTIME]", tty.c_cc[VTIME]);
printf("%20s\t%d\n", "tty.c_cc[VSTATUS]", tty.c_cc[VSTATUS]);
};
#if defined(_TTY_PRINT_MAIN)
int main(void)
{
int fd,c, res;
struct termios oldtio;
struct termios newtio;
char buf[255];
char *modemdevice;
modemdevice = ttyname(STDIN_FILENO);
printf("modemdevice L %s \n", modemdevice);
fd = open(modemdevice, O_RDWR | O_NOCTTY );
if (fd <0) {perror(modemdevice); exit(-1); }
tcgetattr(fd, &oldtio);
ft_terminal_printf(oldtio);
newtio.c_cc[VEOF] = 4; /* Ctrl-d */
newtio.c_cc[VEOL] = 255; /* '\0 ' */
newtio.c_cc[VEOL2] = 255; /* '\0 ' */
newtio.c_cc[VERASE] = 127; /* Ctrl-? del('\177') */
newtio.c_cc[VWERASE] = 23; /* Ctrl-W */
newtio.c_cc[VKILL] = 21; /* Ctrl-U */
newtio.c_cc[VREPRINT] = 18; /* Ctrl-R */
newtio.c_cc[VINTR] = 3; /* Ctrl-C */
newtio.c_cc[VQUIT] = 28; /* Ctrl-\\ */
newtio.c_cc[VSUSP] = 26; /* Ctrl-Z */
newtio.c_cc[VDSUSP] = 25; /* Ctrl-Y */
newtio.c_cc[VSTART] = 17; /* Ctrl-Q */
newtio.c_cc[VSTOP] = 19; /* Ctrl-S */
newtio.c_cc[VLNEXT] = 22; /* Ctrl-V */
newtio.c_cc[VDISCARD] = 15; /* Ctrl-O */
newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */
newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
newtio.c_cc[VSTATUS] = 20; /* Ctrl-T */
/*
VEOF EOF ^D
VEOL EOL _POSIX_VDISABLE
VEOL2 EOL2 _POSIX_VDISABLE
VERASE ERASE ^? ‘\177’
VWERASE WERASE ^W
VKILL KILL ^U
VREPRINT REPRINT ^R
VINTR INTR ^C
VQUIT QUIT ^\\ ‘\34’
VSUSP SUSP ^Z
VDSUSP DSUSP ^Y
VSTART START ^Q
VSTOP STOP ^S
VLNEXT LNEXT ^V
VDISCARD DISCARD ^O
VMIN --- 1
VTIME --- 0
VSTATUS STATUS ^T
*/
close(fd);
}
#endif
보는거와같이 설정의 클래그를 확인하여 해석해보자
bash-3.2$ cc terminal_print.c -D _TTY_PRINT_MAIN
bash-3.2$ ./a.out
modemdevice L /dev/ttys001
================ struct termios ================
tty.c_iflag 27394 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 1 0 0 0 0 0 0 1 0
tty.c_oflag 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
tty.c_cflag 19200 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0
tty.c_lflag 536872399 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 1 1
tty.c_ispeed 38400
tty.c_ospeed 38400
============== c_cc ==================
tty.c_cc[VEOF] 4
tty.c_cc[VEOL] 255
tty.c_cc[VEOL2] 255
tty.c_cc[VERASE] 127
tty.c_cc[VWERASE] 23
tty.c_cc[VKILL] 21
tty.c_cc[VREPRINT] 18
tty.c_cc[VINTR] 3
tty.c_cc[VQUIT] 28
tty.c_cc[VSUSP] 26
tty.c_cc[VDSUSP] 25
tty.c_cc[VSTART] 17
tty.c_cc[VSTOP] 19
tty.c_cc[VLNEXT] 22
tty.c_cc[VDISCARD] 15
tty.c_cc[VMIN] 1
tty.c_cc[VTIME] 0
tty.c_cc[VSTATUS] 20
c_iflag = BRKINT | ICRNL | IXON | IXANY | IMAXBEL | IUTF8
c_oflag = OPOST | ONLCR
c_cflag = CS6 | CS7 | CREAD | HUPCL
c_lflag = ECHOKE | ECHOE | ECHOK | ECHO | ECHOCTL | ISIG | ICANON | IEXTEN | PENDIN
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0
1. c_iflag
~ sigint 시그널을 받음
~ '/r' 을 '/n'으로 변경
~ 입출력 제어를 할 수 있고
~ 다른 문자가 와도 입력을 시작한다
~ 입력큐 다차면 벨울림 ( 삒!)
~ 유니코드로 받아온다
2. o_iflag
~ 출력문자를 터미널 출력에 맞게 변경
~ '\n'을 '\r'\'n' 으로 변경하여 전송한다
3. c_cflag
~ CS6 | CS7 = CSIZE 뭔가 문자 사이즈 설정한거 같고
~ 터미널에 입력을 읽을 수 있다
~ 프로세스 종료하면 잘끝넬수 있도록 도와준다
4. c_lflag
~ echo 설정을 다해주엇고 거의 대부분의 문자를 받아 사용한다 (signal 포함)
~ signal 을 받으면 그에 맞는 kill을 불러오게 설정하엿고
~ 문자를 컴터가 잘 읽는 쪽으로 만들어 준다
~ 개인 사용자 설정에 대하여 가져와주고( 난 뭐 설정한게 없는데??)
4. cc_c
이두개로 값들 설정
https://theasciicode.com.ar/ascii-control-characters/end-of-medium-ascii-code-25.html
https://cer3214.tistory.com/entry/%EC%95%84%EC%8A%A4%ED%82%A4-%EC%BD%94%EB%93%9C%ED%91%9CASCII-Code
아스키 코드표(ASCII Code)
DEC HEX OCT Char DEC HEX OCT Char DEC HEX OCT Char 0 00 000 Ctrl-@ NUL 43 2B 053 + 86 56 126 V 1 01 001 Ctrl-A SOH 44 2C 054 , 87 57 127 W 2 02 002 Ctrl-B STX 45 2D 055 - 88 58 130 X 3 03 003 Ctrl-C ETX 46 2E 056 . 89 59 131 Y 4 04 004 Ctrl-D EOT 47 2F 057
cer3214.tistory.com
이제 만들어 주면 될거같다
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <strings.h>
#include <fcntl.h>
#include <stdlib.h>
void ft_bitprintf(unsigned long data, int index)
{
unsigned long bit;
bit = data;
if (index - 1)
ft_bitprintf(data >> 1, index - 1);
printf("%ld ", bit % 2);
}
void ft_terminal_printf(struct termios tty)
{
//https://www.thinkage.ca/gcos/expl/c/lib/printf.html
printf("================ struct termios ================\n");
printf("%20s\t%10lu\t", "tty.c_iflag", tty.c_iflag);
ft_bitprintf(tty.c_iflag, 32);
printf("\n");
printf("%20s\t%10lu\t", "tty.c_oflag", tty.c_oflag);
ft_bitprintf(tty.c_oflag, 32);
printf("\n");
printf("%20s\t%10lu\t", "tty.c_cflag", tty.c_cflag);
ft_bitprintf(tty.c_cflag, 32);
printf("\n");
printf("%20s\t%10lu\t", "tty.c_lflag", tty.c_lflag);
ft_bitprintf(tty.c_lflag, 32);
printf("\n");
printf("%20s\t%10lu\n", "tty.c_ispeed", tty.c_ispeed);
printf("%20s\t%10lu\n", "tty.c_ospeed", tty.c_ospeed);
printf("\n============== c_cc ==================\n");
printf("%20s\t%d\n", "tty.c_cc[VEOF]", tty.c_cc[VEOF]);
printf("%20s\t%d\n", "tty.c_cc[VEOL]", tty.c_cc[VEOL]);
printf("%20s\t%d\n", "tty.c_cc[VEOL2]", tty.c_cc[VEOL2]);
printf("%20s\t%d\n", "tty.c_cc[VERASE]", tty.c_cc[VERASE]);
printf("%20s\t%d\n", "tty.c_cc[VWERASE]", tty.c_cc[VWERASE]);
printf("%20s\t%d\n", "tty.c_cc[VKILL]", tty.c_cc[VKILL]);
printf("%20s\t%d\n", "tty.c_cc[VREPRINT]", tty.c_cc[VREPRINT]);
printf("%20s\t%d\n", "tty.c_cc[VINTR]", tty.c_cc[VINTR]);
printf("%20s\t%d\n", "tty.c_cc[VQUIT]", tty.c_cc[VQUIT]);
printf("%20s\t%d\n", "tty.c_cc[VSUSP]", tty.c_cc[VSUSP]);
printf("%20s\t%d\n", "tty.c_cc[VDSUSP]", tty.c_cc[VDSUSP]);
printf("%20s\t%d\n", "tty.c_cc[VSTART]", tty.c_cc[VSTART]);
printf("%20s\t%d\n", "tty.c_cc[VSTOP]", tty.c_cc[VSTOP]);
printf("%20s\t%d\n", "tty.c_cc[VLNEXT]", tty.c_cc[VLNEXT]);
printf("%20s\t%d\n", "tty.c_cc[VDISCARD]", tty.c_cc[VDISCARD]);
printf("%20s\t%d\n", "tty.c_cc[VMIN]", tty.c_cc[VMIN]);
printf("%20s\t%d\n", "tty.c_cc[VTIME]", tty.c_cc[VTIME]);
printf("%20s\t%d\n", "tty.c_cc[VSTATUS]", tty.c_cc[VSTATUS]);
};
volatile int STOP=1;
int main(void)
{
struct termios oldtty;
struct termios newtty;
int fd,c, res;
char buf[255];
fd = open(ttyname(STDIN_FILENO), O_RDWR | O_NOCTTY );
if (fd <0) {perror(ttyname(STDIN_FILENO)); exit(-1); }
tcgetattr(fd, &oldtty);
bzero(&newtty, sizeof(struct termios));
newtty.c_iflag = BRKINT | ICRNL | IXON | IXANY | IMAXBEL | IUTF8;
newtty.c_oflag = OPOST | ONLCR;
newtty.c_cflag = CSIZE | CREAD | HUPCL;
newtty.c_lflag = ECHOKE | ECHOE | ECHOK | ECHO | ECHOCTL | ISIG | ICANON | IEXTEN | PENDIN;
newtty.c_ispeed = B38400;
newtty.c_ospeed = B38400;
newtty.c_cc[VEOF] = 4; /* Ctrl-d */
newtty.c_cc[VEOL] = 255; /* '\0 ' */
newtty.c_cc[VEOL2] = 255; /* '\0 ' */
newtty.c_cc[VERASE] = 127; /* Ctrl-? del('\177') */
newtty.c_cc[VWERASE] = 23; /* Ctrl-W */
newtty.c_cc[VKILL] = 21; /* Ctrl-U */
newtty.c_cc[VREPRINT] = 18; /* Ctrl-R */
newtty.c_cc[VINTR] = 3; /* Ctrl-C */
newtty.c_cc[VQUIT] = 28; /* Ctrl-\\ */
newtty.c_cc[VSUSP] = 26; /* Ctrl-Z */
newtty.c_cc[VDSUSP] = 25; /* Ctrl-Y */
newtty.c_cc[VSTART] = 17; /* Ctrl-Q */
newtty.c_cc[VSTOP] = 19; /* Ctrl-S */
newtty.c_cc[VLNEXT] = 22; /* Ctrl-V */
newtty.c_cc[VDISCARD] = 15; /* Ctrl-O */
newtty.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */
newtty.c_cc[VTIME] = 0; /* inter-character timer unused */
newtty.c_cc[VSTATUS] = 20; /* Ctrl-T */
tcsetattr(fd, TCSANOW, &newtty);
ft_terminal_printf(oldtty);
ft_terminal_printf(newtty);
while (STOP)
{
res = read(fd,buf,255);
buf[res]=0;
printf(":%s:%d\n", buf, res);
if (buf[0]=='z') STOP=0;
}
tcsetattr(fd, TCSANOW, &oldtty);
}