1 / 34

Linux System Programming

Linux System Programming. Lecture #5 – 단말기 입출력 제어. 리눅스 장치 파일 (1). 리눅스 장치 파일 (Linux Device File) 리눅스 시스템에서는 저장장치에 저장된 파일이나 디렉토리 그리고 모든 입출력 장치를 동일하게 파일로 취급한다 리눅스 장치 파일 입출력 장치를 접근하기 위해 제공하는 특수 파일 모든 입출력 장치에 대해 일관성 있고 유일한 소프트웨어 인터페이스를 제공함으로써 장치 접근 프로그램 작성을 용이하게 함

orleans
Download Presentation

Linux System Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Linux System Programming Lecture #5 –단말기 입출력 제어

  2. 리눅스 장치 파일 (1) • 리눅스 장치 파일(Linux Device File) • 리눅스 시스템에서는 저장장치에 저장된 파일이나 디렉토리 그리고 모든 입출력 장치를 동일하게 파일로 취급한다 • 리눅스 장치 파일 • 입출력 장치를 접근하기 위해 제공하는 특수 파일 • 모든 입출력 장치에 대해 일관성 있고 유일한 소프트웨어 인터페이스를 제공함으로써 장치 접근 프로그램 작성을 용이하게 함 • ‘/dev’시스템 디렉토리에 모든 장치 파일을 제공되며 정규 파일과 같은 방식으로 접근 가능 • 장치 파일명은 ‘장치표시명(3문자)+serial number’로 구성 • 예: hda1, hda2, dsp, eth0 등 Linux System Programming

  3. 리눅스 장치 파일 (2) • 리눅스 장치 파일(Linux Device File) • 종류 • 문자형 장치 파일 • 문자 단위의 데이터 입출력을 지원하는 장치 파일 • 터미널 장치파일, 프린터 장치파일, 사운드 장치파일 등 • 파일 타입 문자: c • 블록형 장치 파일 • 블록 단위의 데이터 입출력을 지원하는 장치 파일 • 하드디스크 장치파일, 비디오 장치파일 등 • 파일 타입 문자: b • 네트워크 장치 파일 • 네트워크 통신 프로토콜을 지원하는 특수한 형태의 장치파일 • 소켓 파일 등 • 파일 타입 문자: s Linux System Programming

  4. 리눅스 장치 파일 (3) • 리눅스 장치 파일의 입출력 인터페이스 • 장치 파일에 대한 입출력 인터페이스는 정규 파일과 거의 동일하다 • 물리적인 장치의 설정이나 고유 기능을 접근하기 위한 인터페이스를 제외하고는 모두가 동일하다 • 접근 인터페이스 • open() –장치 파일 열기 • close() –장치 파일 닫기 • read() –장치 파일로 부터 데이터 읽기 • write() –장치 파일로 데이터 쓰기 • lseek() –일반적으로 지원하지 않음 • ioctl() –물리적인 장치의 설정이나 고유 기능에 대한 접근 Linux System Programming

  5. 입출력 컨트롤러 리눅스 장치 파일 (4) • 리눅스 장치 파일의 입출력 인터페이스 Linux System Programming

  6. 단말기 장치 파일 (1) • 단말기 장치 • 컴퓨터와 사용자 사이에 인터페이스를 제공하는 하드웨어 장치 • 키보드, CRT 터미널 등으로 구성 • 컴퓨터와의 물리적인 연결 • 시리얼 라인을 이용한 직접적인 연결 • 모뎀과 전화선을 이용한 원격 접속 • 컴퓨터와의 통신 방식 • 보통 컴퓨터와 ASCII 코드를 사용하여 통신 • 비동기 프로토콜을 사용하여 문자 단위 전송 지원 • 전이중(full-duplex) 통신이 가능 –터미널 화면에 문자가 출력되는 동안에 키보드 입력이 가능 • 일반적으로 단말기 장치는 dumb device로 다룬다 Linux System Programming

  7. 단말기 장치 파일 (2) • 단말기 장치 파일 • ‘/dev/ttyxx’형태로 제공 • 현재 사용중인 단말기를 위한 장치 파일: ‘/dev/tty’ • 단말기 장치 드라이버 • 일반적인 입출력 인터페이스 제공 • 입출력 문자 매핑(character mapping)과 입력 버퍼링(buffering)을 수행 • 프로그램이 입력된 문자를 읽어가지 않은 상태에서도 새로운 입력을 받아들일 수 있도록 지원 • 서로 다른 상황에서 각기 다르게 입출력 포트를 구성(configure)할 수 있도록 지원 • ‘stty –a’명령을 통해 현재 단말기 장치에 대한 구성을 살펴볼 수 있다 Linux System Programming

  8. echoing 단말기 입출력 방식 • 단말기 입출력 방식 • 단말기 장치 드라이버에서 제공하는 입출력 방식 • 정규형 입력 모드(Canonical Input Mode) • 비정규형 입력 모드(Non-canonical Input Mode) Linux System Programming

  9. 단말기 장치 입출력 인터페이스 • 단말기 장치 입출력 인터페이스 • open() –단말기 장치 열기 • close() –단말기 장치 닫기 • read() –단말기 장치에서 데이터 읽기 • write() –단말기 장치로 데이터 쓰기 • lseek() –지원하지 않음 Linux System Programming

  10. 단말기 장치 제어: ioctl (1) • ioctl() 시스템 호출 • 장치 입출력 제어 시스템 호출 • 장치 파일에 대해 장치와 관련된 하드웨어 옵션과 드라이버와 관련된 소프트웨어 옵션을 설정하기 위해 제공되는 인터페이스 • 장치 고유의 명령어에 대한 일반적이고 총괄적인 진입점을 제공 • ioctl() 시스템 호출안에서 장치 고유의 다양한 여러 종류의 기능을 제공 • ioctl() 시스템 호출의 제공되는 기능은 장치마다 다르기 때문에 정확한 장치 파일을 접근하여야 한다 Linux System Programming

  11. 단말기 장치 제어: ioctl (2) • 단말기 장치 ioctl() 시스템 호출 Linux System Programming

  12. 단말기 장치 제어: ioctl (3) • 단말기 장치 ioctl() 시스템 호출 • request 인수 Linux System Programming

  13. 단말기 장치 제어: ioctl (4) • 단말기 장치 ioctl() 시스템 호출 • termio 구조체 Linux System Programming

  14. 단말기 장치 제어: ioctl (5) • 단말기 장치 ioctl() 시스템 호출 • termio 구조체 –제어 문자 배열(c_cc 배열) • 제어 문자 중에 특별한 의미를 가지는 8개의 문자를 지정하여 변경할 수 있다 • 변경 가능한 제어 문자의 종류 • 표 5-1, 표 5-2 참조 • VMIN, VTIME 문자는 비정규형 입력 모드에서 의미를 가짐 Linux System Programming

  15. 단말기 장치 제어: ioctl (6) • 단말기 장치 ioctl() 시스템 호출 • termio 구조체 –입력 모드 플래그(c_iflag) • 입력 문자를 다루는 방법을 지정 • 입력 모드 플래그의 종류 • 표 5-3 참조 • 초기값은 모든 비트가 0로 설정(clear) Linux System Programming

  16. 단말기 장치 제어: ioctl (7) • 단말기 장치 ioctl() 시스템 호출 • termio 구조체 –출력 모드 플래그(c_oflag) • 출력 문자 및 출력 동작를 다루는 방법을 지정 • 출력 모드 플래그의 종류 • 표 5-4 참조 • 초기값은 모든 비트가 0로 설정(clear) Linux System Programming

  17. 단말기 장치 제어: ioctl (8) • 단말기 장치 ioctl() 시스템 호출 • termio 구조체 –제어 모드 플래그(c_cflag) • 단말기 입출력 하드웨어의 구성(configuration)을 지정 • 제어 모드 플래그의 종류 • 표 5-5 참조 Linux System Programming

  18. 단말기 장치 제어: ioctl (9) • 단말기 장치 ioctl() 시스템 호출 • termio 구조체 –지역 모드 플래그(c_lflag) • 단말기 기능을 제어하기 위한 선로 규율(line discipline) 모드로서 하드웨어 독립적인 제어 기능을 제공 • 지역 모드 플래그의 종류 • 표 5-6 참조 • 초기값은 모든 비트가 0로 설정(clear) • 주요 모드 • ECHO 모드 –반향(echo) 기능 설정 • ICANON 모드 –정규 입력 처리 기능 설정 • ISIG –시그널 기능 설정 Linux System Programming

  19. 예제 프로그램 #1 (1) • 화면 잠금 프로그램 • 단말기의 시그널 및 echo 설정을 사용하여 화면 잠금 기능을 수행하는 프로그램 #include <stdio.h> #include <signal.h> #include <termio.h> main() { struct termio tty; unsigned short savflags; char key[BUFSIZ], *getkey(); int i; for(i=0; i < NSIG; i++) signal(SIGHUP, SIG_IGN); signal(SIGHUP, SIG_DFL); Linux System Programming

  20. 예제 프로그램 #1 (2) • 화면 잠금 프로그램 char *getkey() { static char line[BUFSIZ]; fputs("Enter password: ", stderr); line[0] = '\337'; /* impossible char */ fgets(line, BUFSIZ, stdin); fputs("\n",stderr); return(line); } ioctl(fileno(stdin), TCGETA, &tty); savflags = tty.c_lflag; tty.c_lflag &= ~(ISIG | ECHO); ioctl(fileno(stdin), TCSETAF, &tty); strcpy(key, getkey()); for(;;) if(strcmp(key, getkey()) == 0) { tty.c_lflag = savflags; ioctl(fileno(stdin), TCSETA, &tty); break; } } Linux System Programming

  21. 비정규 입력 (1) • 단말기 장치의 입력 모드 • 단말기 장치 드라이버에서 제공하는 입력 모드 • 정규 입력(Canonical Input) • 라인 단위 입력을 지원 • NL(new-line) 문자가 입력될 때까지 입력된 문자를 원시 버퍼에 저장하였다가 정규 버퍼에 넘겨 입력을 요구한 프로그램에 전달하는 입력 방식 • C 라이브러리 등에서 제공하는 일반적인 입력 방식 • 비정규 입력(Non-Canonical Input) • NL과 같은 특수 문자를 기다리지 않고 한 문자가 입력되는 즉시 정규 버퍼에 넘겨 입력을 요구한 프로그램에 전달하는 입력 방식 • 전화면 편집기(vi 등), 메뉴 구동 프로그램, 타자 연습 프로그램 등과 같이 입력 문자의 즉각적인 처리를 요구하는 프로그램에 적합 Linux System Programming

  22. 비정규 입력 (2) • 비정규 입력 모드 설정 • ioctl() 시스템 호출을 통해 장치 드라이버 모드을 변경 • 지역 모드 플래그 설정 • ICANON 플래그을 0으로 설정 • 추가적인 ISIG 플래그를 0으로 설정하여 signal 관련 문자 검사를 생략할 수 있음 • 제어 문자 설정 • read() 시스템 호출을 정밀하게 제어 • VMIN(c_cc[4]), VTIME(c_cc[5]) 문자 설정 • VMIN – read() 시스템 호출 반환하기 전까지의 최소 입력 문자 수 • VTIME – read() 시스템 호출을 반환하기 위한 대기 시간(0.1초 단위 설정) • VMIN과 VTIME 설정 –표 5.7 참조 Linux System Programming

  23. 비정규 입력 (3) • 비정규 입력 모드 설정 –예 #include <termio.h> struct termio tdes; int ttyfd; ioctl(ttyfd, TCGETA, &tdes); /* 현재의 플래그 상태값을 얻는다 */ tdes.c_lflag &= ~ICANON; /* 정규모드를 off 한다 */ tdes.c_cc[4] = 64; /* 최소 입력 문자 수를 지정 */ Tdes.c_cc[5] = 2; /* 입력 대기 시간 200ms 지정 */ Linux System Programming

  24. 예제 프로그램 #2 (1) • 타이핑 연습 프로그램 • 단말기의 비정규 입력 모드를 이용하여 타이핑 연습을 수행하는 프로그램 #include <stdio.h> #include <fcntl.h> #include <termio.h> main(argc,argv) int argc; char *argv[]; { char ch, *text = "The quick brown fox jumped over the lazy dog\'s back"; int fd, open(), i, errors = 0, len, strlen(); struct termio tty, savtty; if(isatty(fileno(stdout)) == 0) { fprintf(stderr,"stdout not terminal\n"); exit(1); } Linux System Programming

  25. 예제 프로그램 #2 (2) • 타이핑 연습 프로그램 fd = open("/dev/tty", O_RDONLY); /* /dev/tty : MACHINE DEPENDENT !! */ ioctl(fd, TCGETA, &tty); savtty = tty; tty.c_lflag &= ~(ISIG | ICANON | ECHO); tty.c_cc[VMIN] = 1; /* MIN */ ioctl(fd, TCSETAW, &tty); setbuf(stdout, (char *) NULL); printf("Type beneath th efollowing line\n\n%s\n", text); len = strlen(text); for(i=0; i<len; i++) { read(fd, &ch,1); if(ch == text[i]) putchar(ch); else { putchar('\07'); putchar('*'); errors++; } } ioctl(fd, TCSETAF, &savtty); printf("\n\nnumber of errors: %d\n",errors); } Linux System Programming

  26. 예제 프로그램 #3 (1) • 텍스트 파일 출력 프로그램 • 텍스트 파일을 CRT 화면에 출력하는 프로그램 • 리스팅의 정지 및 재개 기능 지원 #include <stdio.h> #include <fcntl.h> #include <termio.h> main(argc, argv) int argc; char *argv[]; { struct termio tty, savtty; char ch, line[BUFSIZ]; FILE *fp; if ((fp = fopen(argv[1], "r")) == NULL) { printf("Cannot open %s\n", argv[1]); exit(1); } Linux System Programming

  27. 예제 프로그램 #3 (2) • 텍스트 파일 출력 프로그램 ioctl(fileno(stdin), TCGETA, &tty); savtty = tty; tty.c_lflag &= ~(ISIG | ICANON | ECHO); tty.c_cc[VMIN] = 0; /* no characters */ tty.c_cc[VTIME] = 1; /* wait for 100 msec */ ioctl(fileno(stdin), TCSETAW, &tty); while (fgets(line, BUFSIZ, fp) != NULL) { if (read(fileno(stdin), &ch, 1) == 1) { tty.c_cc[VMIN] = 1; /* one char */ ioctl(fileno(stdin), TCSETAF, &tty); } fputs(line, stdout); } ioctl(fileno(stdin), TCSETA, &savtty); fclose(fp); } Linux System Programming

  28. 예제 프로그램 #4 • 시리얼 포트를 통한 파일 전송 프로그램 • 시리얼 라인(또는 모뎀)을 통해 파일을 송수신하는 프로그램 • 리눅스의 cu 프로그램 등 • 시리얼 포트를 원시 입출력 모드로 설정하고 전송 파일을 쓰고 읽기하여 파일을 전송함 • ex5-4 : 시리얼 포트를 원시 입출력 모드를 변환하는 함수 • ex5-5 : 시리얼 포트를 원시 입출력 모드로 변환한 후에 전송한 파일을 시리얼 포트에 써줌으로써 파일을 송신 • ex5-6 : 시리얼 포트를 원시 입출력 모드로 변환한 후에 시리얼 포트에서 데이터 읽기을 수행하여 전송 파일을 수신 • 추가적으로 checksum 검사를 통해 전송 에러를 검출 Linux System Programming

  29. 예제 프로그램 #5 (1) • 라인 에디터(Line Editor) 프로그램 • 각각의 문자들은 입력된 순간에 화면에 표시한다. • ERASE 문자가 입력되면 마지막 입력된 문자를 화면의 현재 위치와 버퍼에서 삭제한다. • KILL 문자가 입력되면 현재 라인의 모든 문자들을 삭제한다. • Ctrl-W 문자가 입력되면 현재 라인의 마지막 단어(word)를 삭제한다. • Ctrl-D 문자가 입력되면 편집기 프로그램 종료한다. • 위에서 언급된 문자 이외의 출력 불가능한 문자가 입력되면 Ctrl-G에 대응되는 경고음을 울린다. • 한 라인의 길이는 80 문자로 하고 80 문자가 넘게 입력되면 단어는 다음 줄의 첫번째 컬럼에 표신한다. Linux System Programming

  30. 예제 프로그램 #5 (2) • 라인 에디터(Line Editor) 프로그램 #include <ctype.h> #include <termio.h> #define EOT '\04' /* cntl -D */ #define BEL '\07' /* cntl -G */ #define ETB '\027' /* cntl -W */ #define MAXLINE 512 #define LINESIZE 80 #define BACKSPACE write(1,"\b \b",3) main(argc,argv) int argc; char *argv[]; { char line[MAXLINE], ch; int pos, newpos, savpos, i; struct termio tty, savetty; Linux System Programming

  31. 예제 프로그램 #5 (3) • 라인 에디터(Line Editor) 프로그램 if(!isatty(0)) { perror(argv[0]); exit(1); } if(ioctl(0,TCGETA,&tty) == -1) { perror(argv[0]); exit(2); } /* turnoff canonical input and echoing */ savetty = tty; tty.c_cc[VMIN] = 1; tty.c_cc[VTIME] = 1; tty.c_lflag &= ~(ISIG | ICANON | ECHO); if(ioctl(0,TCSETAF,&tty) == -1) { perror(argv[0]); exit(3); } pos =0; while(read(0, &ch, 1) > 0) { Linux System Programming

  32. 예제 프로그램 #5 (4) • 라인 에디터(Line Editor) 프로그램 /* if EOF in first position stop */ if(ch == EOT) { if(pos == 0) break; } /* if ERASE character then erase previous character */ else if(ch == tty.c_cc[VERASE]) { if(pos > 0) { BACKSPACE; --pos; } } /* if cntl -W erase until beginning of last word */ else if(ch == ETB) { while(pos > 0 && isspace(line[pos-1])) { BACKSPACE; --pos; /* trailing blanks*/ } while(pos > 0 && !isspace(line[pos-1])) { BACKSPACE; --pos; /* last word */ } } Linux System Programming

  33. 예제 프로그램 #5 (5) • 라인 에디터(Line Editor) 프로그램 /* if new - line start a new line */ else if(ch == '\n') { write(1,&ch, 1); pos = 0; } /* if not printable ring bell instead */ else if(!isprint(ch)) { write(1,BEL,1); } /* write charcter to screen and store it */ else { write(1, &ch, 1); line[pos++] = ch; } /* wrap - around -- OPTIONAL */ if(pos >= LINESIZE && !isspace(ch)) { savpos = pos; /* find begining of last word */ while(pos > 0 && !isspace(line[pos -1])) --pos; Linux System Programming

  34. 예제 프로그램 #5 (6) • 라인 에디터(Line Editor) 프로그램 if(pos > 0) { newpos = 0; /* copy last word to begining of line */ for(i=pos; i< savpos; i++) { BACKSPACE; line[newpos++] = line[i]; } pos = newpos; /* display word at begining of line */ write(1,"\n",1); for(i=0; i<pos; i++) write(1,&line[i], 1); } else write(1,"\n",1); } } /* reset terminal setting */ ioctl(0, TCSETA, &savetty); } Linux System Programming

More Related