일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- pwncollege
- 시스템 프로그래밍
- radare2
- 리눅스 커널
- pwn.college
- 리버싱
- 리눅스
- 드론
- 커널
- 시그널
- 알고리즘
- kernel
- 리눅스커널
- 컴퓨터구조
- 시스템해킹
- wargame
- C언어
- 시스템프로그래밍
- 워게임
- Pwnable.kr
- write up
- css
- 어셈블리어
- 프로그래밍
- Bandit
- 취약점
- px4
- Leviathan
- 시스템
- C++
- Today
- Total
Computer Security
#27 I/O Multiplexing : epoll (실습) 본문
epoll API를 이용해서 inotify fd 와 stdin fd에 대해서 read 이벤트를 감시하고있다가 이벤트가 발생하면 해당 fd에 가서 정보를 읽어오자.
1. 이전에 작성했던 select.c 파일을 epoll.c로 카피한다. 아래는 select.c 코드이다.
2. select 부분을 삭제해주고 int epfd 선언 후 epoll_create를 이용해서 instance를 생성한 뒤, 예외처리 해준다.
#include <sys/epoll.h>
int epoll_create(int size);
int epoll_create1(int flags);
3. struct epoll_event ep_event 선언 후, epoll_ctl API를 통해서 감시를 원하는 fd를 설정 해준다.
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
epfd : epoll instance
op : 수행할 동작
- EPOLL_CTL_ADD : 추가
- EPOLL_CTL_MOD : 변경
- EPOLL_CTL_DEL : 삭제
fd : 감시할 fd
event : 감시 이벤트 명시
epoll event mask | epoll_ctl | epoll_wait | Description |
EPOLLIN | O | O | read 가능 |
EPOLLOUT | O | O | write 가능 |
EPOLLRDHUP | O | O | 연결 종료, 상대방 소켓 셧다운 |
EPOLLPRI | O | O | TCP socket에서 OOB 데이터 수신 등 예외 상황 |
EPOLLERR | X | O | 에러가 발생한 상황 |
EPOLLHUP | X | O | 장애가 발생한 상황 |
EPOLLET | O | X | 이벤트 감지를 엣지 트리거(Edge trigger)로 설정 |
EPOLLONESHOT | O | X | 해당 fd에서는 단 한번의 이벤트만 발생 |
epoll event struct
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event {
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
해당 fd에 대해서 EPOLLIN 이벤트에 대해 감시하게끔 설정 해보자.
과정
1. struct epoll_event event 선언
2. memset 이용해 초기화
3. event.events 안에 EPOLLIN을 넣어준다.
4. event.data.fd 안에 inotify fd인 fd를 넣어준다.
5. epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
6. 예외 처리 해준다.
4. inotify fd에 대해서 감시하는 코드를 위에 3번에서 작성 했으니, STDIN 을 감시하는 코드를 작성하자.
위의 내용과 똑같이 fd 대신 STDIN_FILENO 를 넣어준다.
5. while 문안에서 epoll_wait API를 이용하자.
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
epfd : epoll instance - epfd
events : 발생한 이벤트 정보 - &event
maxevents : events 변수의 최대 엔트리 개수 - 1(1개씩)
timeout : 최대 blocking timeout(milliseconds 단위) - 5000(5초)
과정
1. memset 으로 초기화 해준다.
2. epoll_wait 작성
6. 예외 처리 해준다.
ret == -1 : 에러처리
ret == 0 : timeout
ret > 0 : 이벤트 발생
-FD_ISSET 을 이용해서 어느 fd에서 이벤트가 발생한 것인지 찾아준다.
-inotify 에서 이벤트가 발생을때와 STDIN_FILENO에서 발생했을 때 각각의 코드를 짜준다.
7. 전체 코드이다.
8. gcc 컴파일 후, 실행 시켜보자.
아무것도 안하고 기다리면 5초 뒤, timeout이 뜬다.
다른 터미널을 열어서 vi epoll.c 명령어를 입력하니, 정상적으로 반응 하는 것을 알 수 있다!
'리눅스 시스템 프로그래밍' 카테고리의 다른 글
#29 프로세스 개념, 프로세스 생성(실습) (2) | 2022.10.04 |
---|---|
#28 프로세스 개념, 프로세스 생성 (0) | 2022.10.03 |
#26 I/O Multiplexing : epoll (0) | 2022.10.01 |
#25 I/O Multiplexing(select) (실습) (0) | 2022.09.30 |
#24 I/O Multiplexing(select) (0) | 2022.09.29 |