fd is tty socket file in kernel
해당 글을 읽고 오는것이 좋다.
커널에서 read()가 vfs와 드라이버에서 연결을 한다고 했다. 이 말을 자세히 분석해보자
먼저, read()는 결국 내부적으로는 커널의 시스템콜과 연결이 되어있고 이는 커널 코드로
C
SYSCALL_DEFINE3(read, unsigned int,fd, char__user *, buf,size_t, count)
{
return ksys_read(fd, buf, count);
}다음과 같다.
ksys_read
C
ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count)
{
CLASS(fd_pos, f)(fd);
ssize_t ret = -EBADF;
if (!fd_empty(f)) {
loff_t pos, *ppos = file_ppos(fd_file(f));
if (ppos) {
pos = *ppos;
ppos = &pos;
}
ret = vfs_read(fd_file(f), buf, count, ppos);
if (ret >= 0 && ppos)
fd_file(f)->f_pos = pos;
}
return ret;
}이제 커널 코드를 보면 vfs_read 와 같은게 보인다. 즉, virtual file system 계층인데 이는 모든 리소스 ( 파일 , 소켓 , 터미널 ) 를 파일처럼 다뤄서 파일 종류에 상관없이 동일한 API(read, write, mmap)를 제공하는 공통 계층이다.
그럼 이 계층 뒤에는 실제 파일들에게서 읽어와여 하는데 그 부분은 파일을 관리하는 각각의 드라이버에게 역임한다.
예를 들어,
구체적 드라이버
- 만약 FD가:
- 일반 파일 → 페이지 캐시(page cache) 를 거칩니다. (커널이 디스크 블록을 메모리에 캐싱)
- 파이프/소켓 → 파이프 버퍼 / 소켓 버퍼(sk_buff) 에서 꺼냄
- 터미널(tty) → tty 드라이버가 내부 입력 큐(tty_buffer)에서 문자를 꺼낸다. canonical 모드면 Enter 칠 때까지 거기에 줄 단위로 모여 있음.