πŸ’Ώ KAIST:PINTOS | Concept | File Descriptor

μ΄μˆœκ°„Β·2025λ…„ 5μ›” 22일

KAIST:PINTOS

λͺ©λ‘ 보기
19/23

파일 λ””μŠ€ν¬λ¦½ν„°λž€??

  • μœ μ € ν”„λ‘œμ„ΈμŠ€λŠ” 직접 μ»€λ„μ˜ 파일 ꡬ쑰체에 μ ‘κ·Όν•  수 μ—†λ‹€.
  • κ·Έλž˜μ„œ 컀널은 μœ μ €μ—κ²Œ 숫자 ν•˜λ‚˜(μ •μˆ˜)λ₯Ό μ€€λ‹€.
    그게 λ°”λ‘œ 파일 λ””μŠ€ν¬λ¦½ν„° (File Descriptor, FD)λ‹€.
  • FDλŠ” μœ μ €κ°€ 파일 μž…μΆœλ ₯을 ν•˜κΈ° μœ„ν•œ 간접적인 핸듀이닀.

μ™œ ν•„μš”ν•œκ°€

  • μ‹œμŠ€ν…œ μ½œμ„ 톡해 read(fd, buf, size)처럼 호좜이 λ“€μ–΄μ˜€λ©΄,

    • μœ μ €λŠ” 숫자(FD)만 μ•Œλ©΄ λœλ‹€.
    • 컀널은 κ·Έ 숫자λ₯Ό 기반으둜 struct file *을 μ°Ύμ•„ ν•΄λ‹Ή νŒŒμΌμ— μ ‘κ·Όν•œλ‹€.
  • μœ μ €λŠ” 컀널 λ‚΄λΆ€ κ΅¬ν˜„μ„ λͺ°λΌλ„ νŒŒμΌμ„ μ‘°μž‘ν•  수 μžˆλ‹€.


κΈ°λ³Έ κ·œμΉ™: FD 번호

FD 번호의미
0ν‘œμ€€ μž…λ ₯ (stdin)
1ν‘œμ€€ 좜λ ₯ (stdout)
2ν‘œμ€€ μ—λŸ¬ (stderr) - μ‚¬μš©ν•˜μ§€ μ•ŠμŒ
3β†‘μœ μ €κ°€ open으둜 μ—° νŒŒμΌλ“€

PintOSμ—μ„œμ˜ FD ꡬ쑰

PintOSμ—μ„œλŠ” 각 μŠ€λ ˆλ“œκ°€ μžμ‹ λ§Œμ˜ FD ν…Œμ΄λΈ”μ„ κ°–λŠ”λ‹€.

struct file **fd_table;  // μ—΄λ¦° νŒŒμΌλ“€μ„ κ°€λ¦¬ν‚€λŠ” 포인터 λ°°μ—΄
int fd_idx;              // λ‹€μŒμ— ν• λ‹Ήν•  FD 번호 (보톡 3λΆ€ν„° μ‹œμž‘)
  • fd_table[3] = 파일 A의 포인터
  • fd_table[4] = 파일 B의 포인터
  • ... 이런 μ‹μœΌλ‘œ λ™μž‘ν•œλ‹€.

λ™μž‘ κ³Όμ •

[1] μœ μ €κ°€ νŒŒμΌμ„ μ—°λ‹€

int fd = open("test.txt");

-> 컀널 λ‚΄λΆ€ λ™μž‘:

  1. 파일 μ‹œμŠ€ν…œμ— "test.txt"λΌλŠ” μ΄λ¦„μ˜ 파일이 μ‘΄μž¬ν•˜λŠ”μ§€ 확인
  2. filesys_open()으둜 νŒŒμΌμ„ μ—°λ‹€. 성곡 μ‹œ struct file *fκ°€ λ°˜ν™˜λœλ‹€.
  3. ν”„λ‘œμ„ΈμŠ€μ˜ fd_table[fd_idx] = f둜 μ €μž₯ν•˜κ³ , fd_idx++
  4. FD 번호(μ •μˆ˜)만 μœ μ €μ—κ²Œ 리턴

μœ μ € μž…μž₯에선 파일이 μ•„λ‹ˆλΌ 숫자만 받은 μ…ˆ
컀널은 κ·Έ 숫자λ₯Ό 보고 ν•΄λ‹Ή νŒŒμΌμ„ μ°Ύμ•„ λ™μž‘ν•¨


[2] μœ μ €κ°€ νŒŒμΌμ— write ν•œλ‹€

write(fd, buf, 100);

-> 컀널 λ‚΄λΆ€ λ™μž‘:

  1. 전달받은 fdκ°€ fd_table λ²”μœ„ μ•ˆμ— μžˆλŠ”μ§€ 확인
  2. ν•΄λ‹Ή μœ„μΉ˜μ— struct file *이 μ‘΄μž¬ν•˜λŠ”μ§€ 확인
  3. κ·Έ 파일 ν¬μΈν„°λ‘œ file_write(f, buf, 100) μˆ˜ν–‰

컀널은 fd β†’ struct file * λ³€ν™˜ν•˜λŠ” 과정을 κ±°μΉœλ‹€


[3] μœ μ €κ°€ νŒŒμΌμ„ λ‹«λŠ”λ‹€

close(fd);

-> 컀널 λ‚΄λΆ€ λ™μž‘:

  1. fd_table[fd]κ°€ NULL이 μ•„λ‹Œμ§€ 확인
  2. file_close(fd_table[fd])둜 파일 μžμ› ν•΄μ œ
  3. fd_table[fd] = NULL둜 μ²˜λ¦¬ν•΄ ν•΄λ‹Ή FDλŠ” μž¬μ‚¬μš© κ°€λŠ₯ν•˜κ²Œ λ§Œλ“ λ‹€

FD μœ νš¨μ„± 검사

if (fd < 0 || fd >= FD_LIMIT) return -1;
if (fd_table[fd] == NULL) return -1;
  • FDκ°€ μœ νš¨ν•˜μ§€ μ•Šκ±°λ‚˜ λ‹«νžŒ μƒνƒœμ—μ„œ μ ‘κ·Όν•˜λ©΄ ν…ŒμŠ€νŠΈμ—μ„œ μ‹€νŒ¨ν•œλ‹€
  • 잘λͺ»λœ 포인터 μ ‘κ·ΌμœΌλ‘œ PANIC λ°œμƒ κ°€λŠ₯μ„± 있음

μ£Όμš” κ΅¬ν˜„ 포인트

  • open():

    • 빈 FD 슬둯 탐색
    • 파일 μ—΄κΈ° 및 fd_table 등둝
  • read()/write():

    • FD μœ νš¨μ„± 검증
    • 컀널 ꡬ쑰체둜 λ³€ν™˜ ν›„ read/write μˆ˜ν–‰
  • close():

    • FD에 ν•΄λ‹Ήν•˜λŠ” 파일 λ‹«κ³ , ν…Œμ΄λΈ” NULL 처리

ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€

μ‹œμŠ€ν…œ μ½œκ΄€λ ¨ ν…ŒμŠ€νŠΈ μ˜ˆμ‹œ
open()open-normal, open-null, open-bad-ptr, open-twice
close()close-normal, close-twice, close-bad-fd
read()read-normal, read-bad-fd, read-zero
write()write-normal, write-bad-fd, write-zero

정리

  • 파일 λ””μŠ€ν¬λ¦½ν„°λŠ” μœ μ €μ™€ 컀널 μ‚¬μ΄μ˜ κ³„μ•½λœ μΈν„°νŽ˜μ΄μŠ€λ‹€.
  • FDλ₯Ό 톡해 μœ μ €λŠ” νŒŒμΌμ„ 직접 닀루지 μ•Šκ³ λ„ 컀널을 톡해 μ•ˆμ „ν•˜κ²Œ μž…μΆœλ ₯을 μˆ˜ν–‰ν•  수 μžˆλ‹€.
  • PintOSμ—μ„œλŠ” FD ν…Œμ΄λΈ”μ„ 기반으둜 κ΅¬ν˜„λ˜λ©°,
    open β†’ write/read β†’ close 전체 흐름을 μ΄ν•΄ν•˜κ³  κ΅¬ν˜„ν•΄μ•Ό 정상적인 ν…ŒμŠ€νŠΈ 톡과가 κ°€λŠ₯ν•˜λ‹€.
profile
μ„œνˆ΄μ§€μ–Έμ • 늘 행동이 먼저이기λ₯Ό

0개의 λŒ“κΈ€