일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Pwnable.kr
- 알고리즘
- 시스템해킹
- write up
- 어셈블리어
- css
- 리눅스
- 프로그래밍
- Leviathan
- 리눅스커널
- C언어
- C++
- Bandit
- 시그널
- 워게임
- 시스템 프로그래밍
- pwn.college
- 커널
- 시스템프로그래밍
- kernel
- 리버싱
- wargame
- radare2
- px4
- 드론
- 리눅스 커널
- pwncollege
- 컴퓨터구조
- 취약점
- 시스템
- Today
- Total
Computer Security
#25 I/O Multiplexing(select) (실습) 본문
select API를 이용해서 inotify fd 와 stdin fd에 대해서 read 이벤트를 감시하고있다가 이벤트가 발생하면 해당 fd에 가서 정보를 읽어오자.
이전에 작성했던 inotify 기능을 작성했던 코드에 stdin fd에대해 읽어오는 부분 + select로 I/O Multiplexing 하는 부분을 붙혀서 코드를 작성 해보자.
1. 이전에 작성했던 inotify.c 파일을 select.c로 카피한다. 아래는 inotify.c 코드이다.
메인함수에서부터 inotify객체를 생성하고 watch를 2개 추가한 뒤, while 루프를 해서 read 를 직접적으로 호출하는 예제였다.
우리는 stdin 에대해서도 I/O multiplexing을 해야하니 코드를 수정해야한다.
stdin의 fd는 파일 실행시 이미 열려있는 상태이다. ( fd : STDIN_FILENO )
2. select API를 추가 해주자.
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
파라미터
- nfds : fdset에 포함된 fd 중 가장 큰 값 +1
- readfds : read가 가능한 시점을 감시하기 위한 fd set, NULL 입력 가능
- writefds : write가 가능한 시점을 감시하기 위한 fd set, NULL 입력 가능
- exceptfds : exception이 가능한 시점을 감시하기 위한 fd set, NULL 입력 가능
- timeout :
- non NULL : 최대 block timeout 값 지정
- NULL : 무한 blocking
우리는 inotify fd 와 STDIN_FILENO fd를 두개를 처리해야한다.
while문 안에있는 read 대신 select API를 호출해주자.
과정
i) nfds : fd > STDIN_FILENO ? fd +1 : STDIN_FILENO +1
(inotify fd 와 STDIN_FILENO fd 둘중 가장 큰값을 찾아내서 +1 해줘야 한다.)
ii)readfds
1. fd_set 변수를 선언한 뒤, FD_ZERO를 이용해서 초기화하고, FD_SET으로 설정 해주자.
2. fd를 fds에 설정한다.
3. STDIN_FILENO를 fds에 설정한다.
4. readfds 에 &fds 를 넣어준다.
iii) writefds : NULL
iv) exceptfds : NULL
v) timeout : struct timeval timeout 변수를 선언하고 설정해준다.
Vi) return value의 반환 값을 참고해 예외처리를 해준다.
ret == -1 : 에러처리
ret == 0 : timeout
ret > 0 : 이벤트 발생
-FD_ISSET 을 이용해서 어느 fd에서 이벤트가 발생한 것인지 찾아준다.
-inotify 에서 이벤트가 발생을때와 STDIN_FILENO에서 발생했을 때 각각의 코드를 짜준다.
Vi) 최종 완성된 select 부분 코드이다.
전체적인 흐름
1. fds 초기화
2. inotify , STDIN_FILENO 설정
3. timeout 5초설정
4. select 함수 설정
5. 예외처리를 하면서 FD_ISSET을 이용해서 i) inotify에서 이벤트일 경우 ii) STDIN 이벤트일경우 두가지에 대해 코드를 작성 해준다.
3. 완성된 전체 코드이다.
4. gcc 컴파일을 해준다.
5. ./select 를 이용해 실행 시켜보자.
기다리니 5초에 한번씩 timeout이 발생한다.
다른 터미널을 열어서 vi select 명령어를 입력하니 정상적으로 반응 하는 것을 알 수 있다!
'리눅스 시스템 프로그래밍' 카테고리의 다른 글
#27 I/O Multiplexing : epoll (실습) (0) | 2022.10.02 |
---|---|
#26 I/O Multiplexing : epoll (0) | 2022.10.01 |
#24 I/O Multiplexing(select) (0) | 2022.09.29 |
#23 파일 이벤트 (실습) (0) | 2022.09.28 |
#22 파일 이벤트 (0) | 2022.09.27 |