// 1. 파일디스크립터 식별자, 저장할 메모리 주소, 메모리 크기
ssize_t rio_readn(int fd, void *usrbuf, size_t n)
{
size_t nleft = n; // usrbuf의 남은 메모리 공간
ssize_t nread; // (signed) 읽은 Byte 수 저장할 변수
char *bufp = usrbuf; // 메모리 주소 (이동)
/* 더 이상 읽을 데이터 없을 때까지 */
while (nleft > 0) {
/* fd에서 데이터 읽어 bufp에 저장 (nread : 읽은 Byte 수) */
if ((nread = read(fd, bufp, nleft)) < 0) {
/* sys call(read) 중에 시그널 핸들러에 의해 인터럽트된 상황 */
if (errno == EINTR) // EINTR : 시그널 핸들러에 의한 인터럽트를 나타내는 상수
nread = 0; // errno : sys call 이 실패할 때 설정되는 오류 코드 (전역변수)
/* sys call 오류발생 */
else
return -1;
}
else if (nread == 0) // 더 이상 읽을 데이터가 없음
break; /* EOF */
nleft -= nread; // 처음 n의 크기에서 읽은 Byte 만큼 빼는 작업 반복
bufp += nread; // 읽은 Byte 만큼 메모리 주소 이동
}
return (n - nleft); /* Return >= 0 */
/* 전체 - 남은 공간 = 전체 데이터 크기..? */
}
인자
파일 디스크립터 : 어떤 파일이나 입출력 장치로부터 데이터를 읽을 것인지를 지정
버퍼 : 데이터를 읽어오기 위한 버퍼를 필요
읽기 길이 : 몇 바이트를 읽을 것인지를 지정
반환 값 : 실제로 읽은 바이트 수를 반환
else if (nread == 0)
if (errno == EINTR) ~ else return -1
에러 처리: read 시스템 콜은 오류가 발생할 수 있으므로 처리 필요
다른 프로세스에 의해 발생한 시그널(Signal) 이라고 불리는 이벤트를 처리하는 코드 블록 또는 함수
- 주로 프로세스 간 통신, 오류 및 예외 처리, 프로그램 상태 변경 등을 알리는 데 사용
컴퓨터 시스템에서 하드웨어 또는 소프트웨어 이벤트에 의해 발생하는 중단 또는 강제로 실행되는 이벤트
현재 실행 중인 프로세스의 흐름을 일시적으로 멈추고 , 인터럽트 서비스 루틴(Interrupt Service Routine 또는 ISR)을 실행한 다음, 원래의 프로세스로 돌아가는 방식으로 동작
= if (errno == EINTR) nread = 0; -> 다시 while문 반복
소프트웨어 인터럽트 : 예외 처리 (예: 0으로 나누기), 시스템 콜, 시그널 발생 등의 경우에 발생
하드웨어 인터럽트 : 주로 입출력 장치와 상호 작용하거나, 타이머 등의 하드웨어 이벤트를 처리할 때 발생
📌 시그널 핸들러, 인터럽트 추가 공부 필요..!!