DevLog ๐Ÿ“จ

[DevLog][CSAPP] 10์žฅ ์‹œ์Šคํ…œ ์ˆ˜์ค€ ์ž…์ถœ๋ ฅ (10.1~10.5)

cece00 2023. 9. 24. 15:04

proxy-lab์—์„œ ์†Œ์ผ“ํ†ต์‹ ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ reading

10. ์‹œ์Šคํ…œ ์ˆ˜์ค€ ์ž…์ถœ๋ ฅ

  • ์ž…์ถœ๋ ฅ์€ ๋ฉ”์ธ๋ฉ”๋ชจ๋ฆฌ, ํ„ฐ๋ฏธ๋„, ๋””์Šคํฌ์™€ ๊ฐ™์€ ์žฅ์น˜๋“ค ๊ฐ„์— ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋ณต์ œํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
  • C์—์„œ๋Š” printf, scanf๊ฐ™์€ ๊ฒƒ๋“ค์ด ์‚ฌ์šฉ์ž ์ˆ˜์ค€ ์ž…์ถœ๋ ฅ์„ ์ œ๊ณตํ•œ๋‹ค.
  • ํ•˜์ง€๋งŒ Unix์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์‹œ์Šคํ…œ ์ฝœ ์ˆ˜์ค€์˜ ์ž…์ถœ๋ ฅ (Unix I/O)์„ ์•Œ์•„์•ผ ํ•œ๋‹ค.
    1. ์‚ฌ์šฉ์ž ์ˆ˜์ค€ ์ž…์ถœ๋ ฅ์€ ๋ฌธ์ œ๊ฐ€ ๋งŽ๋‹ค. ๋”ฐ๋ผ์„œ ๋„คํŠธ์›Œํฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์“ธ ์ˆ˜ ์—†๋‹ค.
    2. Unix I/O๋ฅผ ์ดํ•ดํ•˜๋ฉด ๋‹ค๋ฅธ ์‹œ์Šคํ…œ์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.

10.1. Unix I/O

๋„คํŠธ์›Œํฌ, ๋””์Šคํฌ, ํ„ฐ๋ฏธ๋„์„ ๋ชจ๋‘ 'ํŒŒ์ผ'๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. (ํŒŒ์ผ๋กœ ๋ชจ๋ธ๋ง๋œ๋‹ค?) ๋„คํŠธ์›Œํฌ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•œ ํŒŒ์ผ ์ž…์ถœ๋ ฅ์ด ๊ฒฐ๊ตญ ํ†ต์‹ .. ์ด๋‹ค.

๐Ÿ‘€ Unix ํŒŒ์ผ ์‹œ์Šคํ…œ์˜ ์ข…๋ฅ˜
ext๊ฐ€ ํŒŒ์ผ ์‹œ์Šคํ…œ์ด๋‹ค. ์—ฌ๋Ÿฌ ๋ฒ„์ „์ด ์žˆ๋‹ค.

๐Ÿ‘€ File Descriptor
ํŒŒ์ผ์„ ์‹๋ณ„ํ•˜๋Š” ์ž‘์€ ๋น„์Œ์ˆ˜ ์ •์ˆ˜๊ฐ’. ํ”„๋กœ์„ธ์Šค๊ฐ€ ํŒŒ์ผ์„ ์—ด๋ฉด ์ปค๋„์ด ์ด๋ฅผ ํ• ๋‹นํ•ด์ค€๋‹ค. ํŒŒ์ผ์ด ๋‹ซ์œผ๋ฉด ํ• ๋‹น๋˜์—ˆ๋˜ ์‹๋ณ„์ž๊ฐ€ ๊ฐ€์šฉ ์‹๋ณ„์ž ํ’€๋กœ ๋˜๋Œ์•„๊ฐ„๋‹ค. ์œ ๋‹‰์Šค์—์„œ ์‹๋ณ„์ž 0์€ ํ‘œ์ค€์ž…๋ ฅ, 1๋Š” ํ‘œ์ค€์ถœ๋ ฅ, 2์€ ํ‘œ์ค€์—๋Ÿฌ๋‹ค. ํŒŒ์ผ์ด ์—ด๋ฆฌ๋ฉด ์ปค๋„์€ ํ”„๋กœ์„ธ์Šค๋งˆ๋‹ค ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค ํ…Œ์ด๋ธ”์— ์‹๋ณ„์ž์™€ ํŒŒ์ผ์˜ ์ฃผ์†Œ, ํŒŒ์ผ์˜ ํ˜„์žฌ ์œ„์น˜(์˜คํ”„์…‹)๋ฅผ ์ €์žฅํ•œ๋‹ค. (์‹๋ณ„์ž๋Š” ํŒŒ์ผ์˜ ์ฃผ์†Œ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ธ๋ฑ์Šค ์—ญํ• ์„ ํ•œ๋‹ค.) ๋”ฐ๋ผ์„œ ์˜คํ”ˆ ๊ฐ€๋Šฅํ•œ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ์˜ ์ˆ˜๋Š” ๋ณดํ†ต ์ œํ•œ๋˜์–ด์žˆ๋‹ค. (๋‚ด ์ปดํ“จํ„ฐ์—์„œ๋Š” 1048576๊ฐœ)

  1. Open File: ์‹๋ณ„์ž (descriptor) ๋ผ๋Š” ๋น„์Œ์ˆ˜ ์ •์ˆ˜๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  2. Changing the current file position: ํŒŒ์ผ์˜ ์‹œ์ž‘ ์ฃผ์†Œ ๋Œ€๋น„ ํ˜„์žฌ ํŒŒ์ผ์˜ ์œ„์น˜์ด๋‹ค. ํŒŒ์ผ์„ ์ฝ๊ณ  ์“ธ ๋•Œ ๋ณ€ํ™”ํ•œ๋‹ค.
  3. Reading and Writing files: ํ˜„์žฌ ํŒŒ์ผ ์œ„์น˜์—์„œ n๋งŒํผ ํŒŒ์ผ์„ ์ฝ๊ฑฐ๋‚˜ ์“ด๋‹ค.
  4. Closing files: ํŒŒ์ผ ์ ‘๊ทผ์ด ์ข…๋ฃŒ๋˜๋ฉด, ์ปค๋„์— ํŒŒ์ผ์„ ๋‹ซ์•„์ค„ ๊ฒƒ์„ ์š”์ฒญํ•˜๊ณ  ์ปค๋„์€ ํŒŒ์ผ ์‹๋ณ„์ž๋ฅผ ๋‹ค์‹œ ๊ฐ€์šฉ์ƒํƒœ๋กœ ๋งŒ๋“ ๋‹ค.

10.2. File

  1. ์ผ๋ฐ˜ ํŒŒ์ผ: ์ž„์˜์˜ ๋ฐ์ดํ„ฐ์ด๋‹ค. ํ…์ŠคํŠธ ๋˜๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ์ง€๋งŒ ์ปค๋„์˜ ๊ด€์ ์—์„œ๋Š” ๋™์งˆ์˜ ํŒŒ์ผ์ด๋‹ค.
  2. ๋””๋ ‰ํ† ๋ฆฌ: ๋งํฌ๋“ค์˜ ๋ฐฐ์—ด๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. ๊ฐ๊ฐ์˜ ๋””๋ ‰ํ† ๋ฆฌ๋Š” ์ตœ์†Œํ•œ ์ž๊ธฐ ์ž์‹ ๊ณผ ์ž๊ธฐ ๋ถ€๋ชจ๋ผ๋Š” ๋‘ ๊ฐœ์˜ ์—”ํŠธ๋ฆฌ๋ฅผ ๊ฐ–๋Š”๋‹ค. (./, ../)
  3. ์†Œ์ผ“: ๋„คํŠธ์›Œํฌ์ƒ์˜ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์™€ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ํŒŒ์ผ์ด๋‹ค.

๐Ÿ‘€ ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ๋งํฌ๋“ค์˜ ๋ฐฐ์—ด๋กœ ๊ตฌ์„ฑ๋œ๋‹ค?

์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ๋งํฌ๋ž€ ๋‹ค๋ฅธ ๋ง๋กœ '๋””๋ ‰ํ† ๋ฆฌ ์—”ํŠธ๋ฆฌ'์ด๋‹ค. ์ฆ‰, ๋””๋ ‰ํ† ๋ฆฌ๋ž€ ๋””๋ ‰ํ† ๋ฆฌ ์—”ํŠธ๋ฆฌ(ํ–‰)๋“ค์˜ ๋ฐฐ์—ด์ด๋‹ค. ๋””๋ ‰ํ† ๋ฆฌ ์—”ํŠธ๋ฆฌ์—๋Š” ํŒŒ์ผ ์ด๋ฆ„ ๋˜๋Š” ๋””๋ ‰ํ† ๋ฆฌ ์ด๋ฆ„, ์—ฐ๊ฒฐ๋œ inode ๋ฒˆํ˜ธ๊ฐ€ ์ ํ˜€์ ธ ์žˆ๋‹ค. ํŒŒ์ผ์„ ์ฝ๊ณ ์ž ํ•œ๋‹ค๋ฉด (์˜ˆ๋ฅผ ๋“ค์–ด cat ๋ช…๋ น์–ด๋กœ ํ…์ŠคํŠธ ํŒŒ์ผ์„ ์ฝ๋Š”๋‹ค๋ฉด) ์‹œ์Šคํ…œ์€ ๋จผ์ € ํŒŒ์ผ์˜ ์ด๋ฆ„์„ ๊ธฐ์ค€์œผ๋กœ ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ ์—”ํŠธ๋ฆฌ ๋ฐฐ์—ด์—์„œ inode๋ฒˆํ˜ธ๋ฅผ ์ฐพ๊ณ , ๊ทธ ์ฃผ์†Œ๋ฅผ ์ฐธ์กฐํ•˜์—ฌ ์‹ค์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋œ ๋ธ”๋ก์œผ๋กœ ๊ฐ€๊ฒŒ ๋œ๋‹ค. ๋ฐ์ดํ„ฐ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ 4KB๋‹จ์œ„๋กœ ์—ฐ์†๋˜์–ด ์ €์žฅ๋˜๋ฏ€๋กœ (ํŽ˜์ด์ง€) inode๋Š” ํ•˜๋‚˜์˜ ํŒŒ์ผ์„ ์ฝ์–ด์˜ค๊ธฐ ์œ„ํ•œ ๋‹ค์ˆ˜์˜ ๋ฐ์ดํ„ฐ ๋ธ”๋ก ์ฃผ์†Œ๊ฐ’์„ ๊ณ„์ธต์  ๊ตฌ์กฐ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. (Direct Block๊ณผ Indirect Block) -- ๊ทธ๋ž˜์„œ ํ•˜๋‚˜์˜ ๋””๋ ‰ํ† ๋ฆฌ ์•ˆ์—๋Š” ๋™์ผํ•œ ์ด๋ฆ„์˜ ํŒŒ์ผ์„ ๊ฐ€์งˆ ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด๋‹ค.

๐Ÿ‘€ ๋””๋ ‰ํ† ๋ฆฌ์˜ inode์—๋Š” ๋ญ๊ฐ€ ์žˆ์„๊นŒ?
๋””๋ ‰ํ† ๋ฆฌ์˜ inode์—๋„ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋œ๋‹ค. (๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“  ์‹œ๊ฐ„, ์ด๋ฆ„, ๋“ฑ๋“ฑ..) inode์— ์ €์žฅ๋œ ๋ธ”๋ก ์ฃผ์†Œ๊ฐ’์œผ๋กœ ๊ฐ€๋ฉด ๋””๋ ‰ํ† ๋ฆฌ ์—”ํŠธ๋ฆฌ ๋ฐฐ์—ด์ด ์žˆ๋‹ค.

๐Ÿ‘€ inode์˜ (์ฃผ์†Œ๊ฐ’์ด ์•„๋‹Œ) ๋ฒˆํ˜ธ๋งŒ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ์„๊นŒ?

์ด๋Š” Unix ์Šคํƒ€์ผ ํŒŒ์ผ ์‹œ์Šคํ…œ์—์„œ๋Š” ๋Œ€๋ถ€๋ถ„ inode๋ฅผ ๋น„๋กฏํ•œ ํŒŒ์ผ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ณต๊ฐ„์˜ ์‹œ์ž‘์ฃผ์†Œ์™€ ์‚ฌ์ด์ฆˆ๊ฐ€ ๊ณ ์ •๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•˜๋‹ค. ํŒŒ์ผ ์‹œ์Šคํ…œ๋งˆ๋‹ค ํ•˜๋‚˜์˜ inode๋ธ”๋ก ํฌ๊ธฐ๋Š” ๋ชจ๋‘ ๊ฐ™๊ณ , ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ณต๊ฐ„์˜ ํฌ๊ธฐ (์ผ๋ฐ˜์ ์œผ๋กœ ์ „์ฒด ํŒŒ์ผ์‹œ์Šคํ…œ์˜ 1%)๋„ ์ •ํ•ด์ ธ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— inode์˜ ๋ฒˆํ˜ธ๋งŒ์œผ๋กœ ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. +) ํŒŒ์ผ ์‹œ์Šคํ…œ ์ž์ฒด์— ๋Œ€ํ•œ ์ฃผ์š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ณต๊ฐ„์„ '์Šˆํผ๋ธ”๋ก'์ด๋ผ๊ณ  ํ•œ๋‹ค.

๋ฆฌ๋ˆ…์Šค ๋””๋ ‰ํ† ๋ฆฌ ๊ณ„์ธต๊ตฌ์กฐ

Linux_Dir_Hierarchy

10.3. ํŒŒ์ผ ์—ด๊ธฐ์™€ ๋‹ซ๊ธฐ

open() & close()

int open(char* filename, int flags, mode_t mode);
int close(int fd);

ํŒŒ์ผ ์—ด๊ธฐ ํ•จ์ˆ˜๋Š” ํŒŒ์ผ ์ด๋ฆ„ filename๊ณผ ์—ด๊ธฐ ๋ชจ๋“œ flag, ์ ‘๊ทผ ๊ถŒํ•œ์„ ์„ค์ •ํ•˜๋Š” mode๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„ ํŒŒ์ผ ์‹๋ณ„์ž file descriptor๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๊ตฌ์ฒด์ ์œผ๋กœ๋Š”, ํŒŒ์ผ ์ด๋ฆ„์œผ๋กœ inode๋ฅผ ์ฐพ๊ณ , ๊ทธ inode ๋ธ”๋ก ์ฃผ์†Œ๋ฅผ ํ”„๋กœ์„ธ์Šค์˜ File Descriptor Table์— ์—”ํŠธ๋ฆฌ๋กœ ์ƒ์„ฑํ•œ๋‹ค.

flag์™€ mode์ธ์ž๋ฅผ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด ๋น„ํŠธ๋งˆ์Šคํฌ๊ฐ€ ์ด์šฉ๋œ๋‹ค.

๐Ÿ‘€ umask?

๋ช…๋ น์ค„์—์„œ ls -l์„ ์น˜๋ฉด ํŒŒ์ผ ์ด๋ฆ„ ์˜†์— drwx..๋กœ ๋œ 10์ž๋ฆฌ ๋ฌธ์ž๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์—ฐ์Šต๋ฌธ์ œ 10.1.

#include "csapp.c"

int main() {
  int fd1, fd2;
  umask(DEF_UMASK);

  fd1 = Open("foo.txt", O_RDONLY | O_CREAT, DEF_MODE);
  Close(fd1);

  fd2 = Open("hello.txt", O_RDONLY | O_CREAT, DEF_MODE);
  printf("fd2 = %d\n", fd2);
  Close(fd2);

  return 0;
}

fd2 = 3์„ ์ถœ๋ ฅํ•œ๋‹ค. 0, 1, 2๋Š” ํ‘œ์ค€์ž…๋ ฅ, ์ถœ๋ ฅ, ์—๋Ÿฌ๋ฅผ ์œ„ํ•ด ์˜ˆ์•ฝ๋˜์–ด ์žˆ๋‹ค.

10.4. ํŒŒ์ผ ์ฝ๊ธฐ์™€ ์“ฐ๊ธฐ

read() & write()

ssize_t read(int fd, void* buf, size_t n);
ssize_t write(int fd, const void *buf, size_t n);

์ฝ๊ธฐ ํ•จ์ˆ˜๋Š” ์ธ์ž๋กœ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ์™€ ํŒŒ์ผ์„ ์ฝ์–ด์˜ฌ ๋ฒ„ํผ์˜ ํฌ์ธํ„ฐ, ์ฝ์„ ์‚ฌ์ด์ฆˆ๋ฅผ ๋ฐ”์ดํŠธ ๋‹จ์œ„๋กœ ๋ฐ›์•„ ์ •์ƒ์ ์œผ๋กœ ์ฝ์–ด์˜จ ๊ฒฝ์šฐ ์ฝ์€ ๋ฐ”์ดํŠธ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด -1์„ ๋ฆฌํ„ดํ•œ๋‹ค. ์“ฐ๊ธฐ ํ•จ์ˆ˜๋Š” ์ธ์ž๋กœ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ, ํŒŒ์ผ์— ์“ธ ๋‚ด์šฉ์ด ๋‹ด๊ธด ๋ฒ„ํผ์˜ ํฌ์ธํ„ฐ, ์“ธ ์‚ฌ์ด์ฆˆ๋ฅผ ๋ฐ›์•„์„œ ํŒŒ์ผ์— ์“ฐ๊ณ , ์“ด ๋ฐ”์ดํŠธ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค. ๋น„์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๋œ ๊ฒฝ์šฐ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ -1์ด๋‹ค.

Short Count

์š”์ฒญํ•œ ๊ฒƒ ๋ณด๋‹ค ๋” ์งง์€ ๋ฐ”์ดํŠธ๋งŒ ์ฝ๊ฑฐ๋‚˜ ์“ฐ๋Š” ๊ฒƒ. ์–ด๋–ค ๊ฒฝ์šฐ์— ๋ฐœ์ƒํ• ๊นŒ?

  1. EOF๋ฅผ ๋งŒ๋‚˜๋ฉด ๊ฑฐ๊ธฐ๊นŒ์ง€๋งŒ ์ฝ๋Š”๋‹ค. ๋”ฐ๋ผ์„œ 50์„ ์š”์ฒญํ•ด๋„ 20 ํ›„์— EOF๊ฐ€ ์žˆ๋‹ค๋ฉด 20๋งŒ ์ฝ๋Š”๋‹ค.
  2. ํ„ฐ๋ฏธ๋„์—์„œ ํ…์ŠคํŠธ ์ค„์„ ์ฝ๊ณ ์ž ํ•  ๋•Œ, ๋ฒ„ํผ ์‚ฌ์ด์ฆˆ๊ฐ€ ๋‚ด๊ฐ€ ์š”์ฒญํ•œ ๊ฒƒ๋ณด๋‹ค ์ž‘์œผ๋ฉด ์งง์€ ์นด์šดํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
  3. ๋„คํŠธ์›Œํฌ ์†Œ์ผ“์„ ์ฝ๊ฑฐ๋‚˜ ์“ธ ๋•Œ. ๋‚ด๋ถ€ ๋ฒ„ํผ๋ง ์ œ์•ฝ๊ณผ ๊ธด ๋„คํŠธ์›Œํฌ ์ง€์—ฐ์œผ๋กœ ์ธํ•ด ์งง์€ ์นด์šดํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

10.5. RIO Package

Robust I/O Package. ์งง์€ ์นด์šดํŠธ๋ฅผ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” IOํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.

1) ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜์ค€์˜ ๋ฒ„ํผ๊ฐ€ ์—†๋Š” ์ž…๋ ฅ/์ถœ๋ ฅ ํ•จ์ˆ˜

ssize_t rio_readn(int fd, void* usrbuf, size_t n) {
  size_t nleft = n;
  ssize_t nread;
  char* bufp = usrbuf;

  while (nleft > 0) {
    if ((nread = read(fd, bufp, nleft)) < 0) {
      if (errno == 4) /* read๊ฐ€ ์ฝ์–ด์˜ค์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ */
        nread = 0;
      else
        return -1;
    } else if (nread == 0) /* end of file */
      break;
    nleft -= nread;
    bufp += nread;
  }
  return (n - nleft); /* ์ฝ์–ด์˜จ ๋ฐ”์ดํŠธ์ˆ˜*/
}
ssize_t rio_writen(int fd, void* usrbuf, size_t n) {
  size_t nleft = n;
  ssize_t nwritten;
  char* bufp = usrbuf;

  while (nleft > 0) {
    if ((nwritten = write(fd, bufp, nleft)) < 0) {
      if (errno == 4)
        nwritten = 0;
      else
        return -1;
    }
    nleft -= nwritten;
    bufp += nwritten;
  }
  return n;
}

2) ๋ฒ„ํผ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ž…๋ ฅ ํ•จ์ˆ˜

typedef struct {
  int rio_fd;                 // ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ
  int rio_cnt;                // ํ˜„์žฌ๊นŒ์ง€ ๋ฒ„ํผ์— ์ฝ์–ด์˜จ ๋ฐ”์ดํŠธ์ˆ˜
  char* rio_bufptr;           // ํ˜„์žฌ IO์œ„์น˜
  char rio_buf[RIO_BUFSIZE];  // ๋‚ด๋ถ€๋ฒ„ํผ
} rio_t;

// rp ์ดˆ๊ธฐํ™”
void rio_readinitb(rio_t* rp, int fd) {
  rp->rio_fd = fd;               // ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ
  rp->rio_cnt = 0;               // ์•„์ง ์ฝ์ง€ ๋ชปํ•จ
  rp->rio_bufptr = rp->rio_buf;  // ๋ฒ„ํผ๋Š” ์‹œ์ž‘ ์ง€์ ์„ ๊ฐ€๋ฆฌํ‚ด
}
// size_n ์€ ์ฝ์–ด์•ผ ํ•  ์–‘
// buf_size ํ•œ๋ฒˆ์— ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ์–‘
ssize_t rio_read(rio_t* rp, void* usrbuf, size_t n) {
  int cnt;

  while (rp->rio_cnt <= 0) {
    rp->rio_cnt = read(rp->rio_fd, rp->rio_buf,
                       sizeof(rp->rio_buf));  // ๋ฒ„ํผ ์‚ฌ์ด์ฆˆ๋งŒํผ
    if (rp->rio_cnt < 0) {
      if (errno == 4) return -1;  // ๋งŒ์•ฝ errno == 4์ด๋ฉด ๋ฐ˜๋ณต๋ฌธ์„ ๋ˆ๋‹ค

    } else if (rp->rio_cnt == 0)  // ์ฝ์€ ๊ฒŒ ์—†์Œ
      return 0;
    else
      rp->rio_bufptr = rp->rio_buf;  // usrbuf๋กœ ๋ณต์ œ๋ฅผ ์‹œ์ž‘ํ•ด์•ผ ํ•  ์œ„์น˜๋กœ ์ด๋™
  }

  cnt = n;
  if (rp->rio_cnt < n) cnt = rp->rio_cnt;  // cnt๋Š” ์‹ค์ œ ์ฝ์–ด์˜จ ์ˆ˜
  memcpy(usrbuf, rp->rio_bufptr, cnt);
  rp->rio_bufptr += cnt;
  rp->rio_cnt -= cnt;

  return cnt;
}

ssize_t rio_readnb(rio_t* rp, void* usrbuf, size_t n) {
  size_t nleft = n;
  ssize_t nread;
  char* bufp = usrbuf;

  while (nleft > 0) {
    if ((nread = rio_read(rp, bufp, nleft)) < 0) {
      return -1;  // 4๋ฒˆ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ์žฌ์‹œ์ž‘์€ rio_read์—์„œ ์ฒ˜๋ฆฌ

    } else if (nread == 0)
      break;
    nleft -= nread;
    bufp += nread;
  }
  return (n - nleft);
}

๐Ÿ‘€ ๋ฒ„ํผ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ญ๊ฐ€ ์ข‹์€๊ฐ€?

read, write๋Š” ์‹œ์Šคํ…œ ์ฝœ์ด๋ฏ€๋กœ ํ•œ๋ฒˆ์— ๋„ˆ๋ฌด ๋งŽ์€ ์‚ฌ์ด์ฆˆ๋ฅผ ์š”์ฒญํ•˜๊ฑฐ๋‚˜, ๋„ˆ๋ฌด ์ž์ฃผ ์š”์ฒญํ•  ์‹œ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ „์ฒด ์‚ฌ์ด์ฆˆ๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ๋‚˜๋ˆ„์–ด์„œ ๋ฒ„ํผ์— ์˜ฎ๊ธฐ๊ณ , ๊ทธ๊ฑธ ๋‹ค์‹œ usrbuf, ์ฆ‰ ๋ณต์ œ๊ฐ€ ๋˜์–ด์•ผ ํ•˜๋Š” ๋ชฉ์ ์ง€๋กœ ์˜ฎ๊ธฐ๋Š” ๊ฒƒ์ด I/O์˜ ํšจ์œจ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ‘€ ์˜ค๋ฒ„ํ—ค๋“œ?

์–ด๋–ค ์ผ์„ ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ„์ ‘์ ์ธ ์ฒ˜๋ฆฌ ๋น„์šฉ(์‹œ๊ฐ„ ๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ)

๐Ÿ‘€ while๋ฌธ์€ ์™œ ์žˆ์„๊นŒ?

์‹œ์Šคํ…œ ์ฝœ read๋Š” ์—ฌ๋Ÿฌ ์›์ธ๋“ค๋กœ ์ธํ•ด ์ฝ์–ด์•ผ ํ•  ๊ฒƒ์„ '๋‹ค ๋ชป ์ฝ๋Š”' ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋Ÿฌํ•œ read ์‹œ์Šคํ…œ ํ˜ธ์ถœ์˜ ํŠน์„ฑ์„ ๊ณ ๋ คํ•ด์„œ, ๋งŒ์•ฝ errno == EINTR์ธ ๊ฒฝ์šฐ, ์ฆ‰ 4๋ฒˆ ์˜ค๋ฅ˜์ธ ๊ฒฝ์šฐ์— while๋ฌธ์ด ๋Œ์•„์„œ ๋‹ค์‹œ ์ฝ์–ด์˜จ๋‹ค.

๐Ÿ‘€ 4๋ฒˆ ์˜ค๋ฅ˜?

์‹œ์Šคํ…œ ์ฝœ์ด ์ธํ„ฐ๋ŸฝํŠธ ์‹œ๊ทธ๋„์— ์˜ํ•ด ์ค‘๋‹จ๋˜์—ˆ์Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์˜ค๋ฅ˜ ์ฝ”๋“œ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ‚ค๋ณด๋“œ ํ‚ค๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ๋‚˜ ๋„คํŠธ์›Œํฌ ์นด๋“œ(NIC)์— ๋ฐ์ดํ„ฐ ํŒจํ‚ท์ด ๋„์ฐฉํ•˜๋ฉด ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ธํ„ฐ๋ŸฝํŠธ๋กœ ์ธํ•ด ์‹œ์Šคํ…œ ์ฝœ์˜ ์ค‘๋‹จ์„ ์š”์ฒญํ•˜๋Š” ์‹œ๊ทธ๋„์ด ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ, ๋จผ์ € ์ธํ„ฐ๋ŸฝํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•œ ํ›„ read, write๋ฅผ ์žฌ์‹œ์ž‘ํ•˜๋„๋ก ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ‘€ ์†Œ์ผ“์˜ ์‹๋ณ„์ž์— ์ฝ๊ฑฐ๋‚˜ ์“ฐ๋ฉด ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ ๊นŒ?

ํŒŒ์ผ๊ณผ ๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•˜์ง€๋งŒ, ์†Œ์ผ“์€ ์ผ๋ฐ˜ ํŒŒ์ผ์€ ์•„๋‹ˆ๋‹ค. ๋Œ€์‹ , ์†Œ์ผ“ ๋””์Šคํฌ๋ฆฝํ„ฐ์— writeํ•˜๋ฉด ์ปค๋„ ๋ฉ”๋ชจ๋ฆฌ๋กœ ๋ฒ„ํผ ๋‚ด์šฉ์ด ๋ณต์ œ๋œ๋‹ค. ์ปค๋„์€ ์†Œ์ผ“์˜ ์—ฐ๊ฒฐ ์ƒํƒœ, ํ”„๋กœํ† ์ฝœ์„ ๋ฐ”ํƒ•์œผ๋กœ writeํ•œ ๋‚ด์šฉ์„ ํŒจํ‚ทํ™”, ํ”„๋ ˆ์ž„ํ™”ํ•˜์—ฌ ๋„คํŠธ์›Œํฌ ์–ด๋Œ‘ํ„ฐ์˜ ๋ฒ„ํผ๋กœ ๋ณต์ œํ•œ๋‹ค. (Direct Memory Access๋ฅผ ํ•œ๋‹ค.) ๋„คํŠธ์›Œํฌ ์–ด๋Œ‘ํ„ฐ์—์„œ๋ถ€ํ„ฐ ๋„คํŠธ์›Œํฌ์ƒ์œผ๋กœ ์ „์†ก๋œ๋‹ค. (๋จผ์ € ๋ผ์šฐํ„ฐ๋กœ ์ „๋‹ฌ๋˜๊ณ , ๋ผ์šฐํ„ฐ๊ฐ€ ๋‹ค์‹œ ํ”„๋ ˆ์ž„์„ ๊นŒ์„œ ์–ด๋””๋‹ค ๋ณด๋‚ผ์ง€ ๊ฒฝ๋กœ์ง€์ •ํ•˜๊ณ ..)