π Get_Next_Line: βμνβλ₯Ό κΈ°μ΅νλ€λ κ²μ μλ―Έ
λ§μ½ μ»΄ν¨ν°μκ² κΈ°μ΅μ΄ μλ€λ©΄ μ΄λ»κ² λ κΉ? λͺ¨λ μ°μ°μ κ·Έμ μΌνμ±μΌλ‘ λλκ³ , λ°©κΈ μ μ νλ μμ
μ λ€μ μ΄μ΄κ°λ κ²μ λΆκ°λ₯ν κ²μ΄λ€. libftκ° CμΈμ΄μ λ¬Έλ²κ³Ό λ©λͺ¨λ¦¬ μ‘°μμ΄λΌλ βνμβμ μ§μ€νλ κ³Όμ μλ€λ©΄, get_next_line(μ΄ν GNL)μ μ»΄ν¨ν°κ° μ΄λ»κ² βμν(state)βλ₯Ό κΈ°μ΅νκ³ μ°μμ μΈ μμ
μ μ²λ¦¬νλμ§μ λν κΉμ ν΅μ°°μ μꡬνλ, μμ ν μλ‘μ΄ μ°¨μμ λμ μ΄μλ€.
βνμΌμμ ν μ€μ© μ½μ΄μ€λΌβλ λͺ
μ λ λ¨μν΄ λ³΄μλ€. νμ§λ§ μ΄λ΄ κΉ¨λ¬μλ€. μ΄κ²μ λ¨μν νμΌμ μ½λ κΈ°μ μ λμ΄, βμκ°βμ΄λΌλ μΆ μμμ λ°μ΄ν°μ νλ¦μ μ μ΄νκ³ , ν¨μμ μλͺ
μ£ΌκΈ°λ₯Ό λ°μ΄λλ βκΈ°μ΅βμ ꡬνν΄μΌ νλ λ¬Έμ λΌλ κ²μ. CμΈμ΄μ μ μμ€(low-level) νμΌ μ
μΆλ ₯κ³Ό μ¨λ¦νλ©°, staticμ΄λΌλ ν€μλμ λ΄κΈ΄ μ² νμ λΉλ‘μ μ΄ν΄νκ² λ μ¬μ μ΄μλ€.
π§ ν΅μ¬ κ°λ μ 볡νκΈ° (Conquering Core Concepts)
GNLμ μΈκ³λ‘ λ€μ΄κ°κΈ° μν΄μ , μ»΄ν¨ν°μ κ°μ₯ κΈ°λ³Έμ μΈ μν΅ λ°©μμ λ¨Όμ μ΄ν΄ν΄μΌ νλ€.
1. νμΌ λμ€ν¬λ¦½ν°(File Descriptor): μΆμνμ 첫걸μ
μ°λ¦¬κ° ν€λ³΄λλ₯Ό λλλ¦¬κ³ , λͺ¨λν°λ₯Ό λ³΄κ³ , νμΌμ μ½λ λͺ¨λ νμλ μ΄μ체μ (OS)μ λμλ κ·Έμ βλ°μ΄ν°μ νλ¦βμΌ λΏμ΄λ€. OSλ μ΄ λ³΅μ‘ν μ₯μΉλ€μ 0(νμ€ μ
λ ₯), 1(νμ€ μΆλ ₯), 2(νμ€ μλ¬)μ κ°μ μ μ λ²νΈλ‘ λ¨μννμ¬ μ°λ¦¬μκ² μ 곡νλ€. μ΄κ²μ΄ λ°λ‘ νμΌ λμ€ν¬λ¦½ν°(FD)λ€. open() ν¨μλ₯Ό ν΅ν΄ νμΌμ μ΄λ©΄, OSλ μλ‘μ΄ λ²νΈνλ₯Ό λ°κΈνλ©° βμ, μ΄μ μ΄ λ²νΈλ‘ νμΌκ³Ό μν΅ν΄βλΌκ³ λ§ν΄μ£Όλ κ²κ³Ό κ°λ€. GNLμ μ΄ λ²νΈν νλμ μμ§ν΄ κ±°λν νμΌμ λ΄μ©μ ν μ€μ© νννλ νν΄μ¬μ κ°μλ€.
2. read()μ BUFFER_SIZE: κ²½κ³ μμ μ€νκΈ°
GNLμ μ μΌν 무기λ read ν¨μμλ€. μ΄ ν¨μλ BUFFER_SIZEλΌλ μ ν΄μ§ ν¬κΈ°λ§νΌλ§ λ°μ΄ν°λ₯Ό κ°μ Έμ¨λ€. μ¬κΈ°μ GNLμ λ³Έμ§μ μΈ λλ λ§κ° μμλλ€. μ°λ¦¬κ° μ½μΌλ €λ βν μ€βμ΄λΌλ κ°λ
μ μ§κ·Ήν μΈκ°μ μΈ λ¨μμ΄μ§λ§, μ»΄ν¨ν°λ κ·Έμ λ°μ΄νΈ(byte)μ νλ¦μΌλ‘ μΈμμ λ³Έλ€.
BUFFER_SIZEκ° ν μ€λ³΄λ€ μμΌλ©΄, κ°ν λ¬Έμ(\n)λ₯Ό λ§λ λκΉμ§ μ¬λ¬ λ²readλ₯Ό νΈμΆν΄μΌ νλ€.BUFFER_SIZEκ° ν μ€λ³΄λ€ ν¬λ©΄, ν μ€μ μ½κ³ λ λ°μ΄ν°κ° λ²νΌμ λ¨λλ€.
λ°λ‘ μ΄ βλ¨μλ²λ¦° λ°μ΄ν°βλ₯Ό μ΄λ»κ² μ²λ¦¬ν κ²μΈκ°? μ΄λ² νΈμΆμμ λ¨μ λ°μ΄ν°λ₯Ό λ€μ νΈμΆμ μν΄ μ΄λκ°μ κ³ μ΄ λ³΄κ΄ν΄λμ΄μΌλ§ νλ€. ν¨μκ° νΈμΆλκ³ λλλ μ°°λμ μκ°μ λμ΄, λ€μμ κΈ°μ½νλ βκΈ°μ΅βμ΄ νμνλ€.
3. λ§λ²μ ν€μλ, static: ν¨μμ μνΌμ λΆμ΄λ£λ€
μ΄ λ¬Έμ μ ν΄λ΅μ λ°λ‘ static λ³μμ μλ€. β¨
char *get_next_line(int fd)
{
static char *backup;
// ...
}
ν¨μκ° λλλ©΄ μ¬λΌμ§λ μΌλ° μ§μ λ³μμ λ¬λ¦¬, static λ³μλ νλ‘κ·Έλ¨μ΄ μμλ λ λ¨ ν λ² λ©λͺ¨λ¦¬μ ν λΉλμ΄ νλ‘κ·Έλ¨μ΄ λλ λκΉμ§ μμ μ κ°μ μ μ§νλ€. μ¦, GNL ν¨μκ° μμ, μλ°± λ² νΈμΆλμ΄λ backup λ³μλ λ§μΉ μ΄μ μ μΌμ κΈ°μ΅νλ μ¬λμ²λΌ, μ΄μ μ μ½κ³ λ¨κ²¨λ λ°μ΄ν°λ₯Ό κ°μ§νκ³ μλ κ²μ΄λ€.
μ΄ static λ³μ backupμ readλ‘ μ½μ΄μ¨ λ΄μ©μ κ³μ μ΄μ΄ λΆμ΄κ³ (strjoin), κ°ν λ¬Έμλ₯Ό λ°κ²¬νλ©΄ κ·Έ μλΆλΆκΉμ§λ₯Ό μΈμμ λ΄λ³΄λ΄κ³ (return), backupμλ κ°ν λ¬Έμ λ€μ λλ¨Έμ§ μ½μμ λ΄μλλ κ². μ΄ λ‘μ§μ κΉ¨λ¬μμ λ, λλ λΉλ‘μ ν¨μμμ μμ£Ό κΈ°λ³Έμ μΈ βμνβλΌλ κ±Έ 보κ΄νλ λ°©λ²μ λ°°μΈ μ μμλ€.
π οΈ λμ GNL ꡬνκΈ° (My GNL Implementation Journey)
κ·Έλ¬λ μλ€μνΌ λ¨Έλ¦¬λ‘ μ΄ν΄νλ κ²κ³Ό μμΌλ‘ ꡬννλ κ²μ μ²μ§ μ°¨μ΄λ€.
- μ½κ³ , μκ³ , λ μκ³ :
readν¨μκ° λ μ΄μ μ½μ κ²μ΄ μμ λκΉμ§, λλ κ°νμ λ§λ λκΉμ§ λ°λ³΅λ¬Έμ λμλ€.backupμ΄λΌλ 곡κ°μBUFFER_SIZEλ§νΌμ λ²½λμ κ³μν΄μ μμ μ¬λ¦¬λ κ³Όμ μ΄μλ€. μ΄ κ³Όμ μμft_strjoinμ λμ λ λ ν μλ©νΈκ° λμ΄μ£Όμλ€. - μλ₯΄κ³ , λ΄λ³΄λ΄κ³ : λ§μΉ¨λ΄ κ°νμ΄λΌλ μ΄μ νλ₯Ό λ§λλ©΄, κ·Έκ³³κΉμ§μ κΈΈμ μλΌλ΄μ΄ κ²°κ³Όλ‘ λ°ννλ€.
- κΈ°μ΅νκ³ , μ€λΉνκ³ : κ·Έλ¦¬κ³ κ°μ₯ μ€μνλ λ¨κ³.
backupλ³μμλ μλΌλ΄κ³ λ¨μ λλ¨Έμ§ λΆλΆμ λ΄μ, λ€μ νΈμΆμ μμμ μ΄ λ μ μλλ‘ μ€λΉμμΌ°λ€. μ΄ κ³Όμ μμ μμμ΄ ν°μ Έ λμ€λ λ©λͺ¨λ¦¬ λμ(leak)λ₯Ό λ§κΈ° μν΄freeμ μ¬ν¬λ₯Ό λ²μλ€. μ λ§ μ΄ λΆλΆμμ μκΈΈ μ μλ μλ¬, νΉν λ°λ³΅λλλ° λ΄κ° λμΉμ§ μμΌλ €λ©΄ ꡬ쑰μ μΌλ‘ μκ°ν΄μΌ νκ³ , CμΈμ΄κ° μ κ·Έν λ‘ μ κ΅ν λ©λͺ¨λ¦¬ κ΄λ¦¬λ₯Ό μꡬνλμ§ μ¨λͺΈμΌλ‘ κΉ¨λ¬μλ€. (μ λ§μ΄μ§, μΈκ·Έν΄ νλ©΄μ λ€μ λ³΄κ³ μΆμ§ μλ€β¦ π)
⨠보λμ€: μ¬λ¬ κ°μ κΈ°μ΅μ λμμ (Bonus: Multiple States at Once!)
νμ ννΈμ GNLμ static λ³μ νλμ μμ‘΄νκΈ°μ, μ€μ§ νλμ κΈ°μ΅(νμΌ)λ§ μ μ§ν μ μμλ€. νμ§λ§ 보λμ€ ννΈλ μ¬λ¬ νμΌμ λμμ μ΄κ³ , κ° νμΌμ μ½κΈ° μνλ₯Ό λ
립μ μΌλ‘ κΈ°μ΅νλΌλ λ λμ μ°¨μμ κ³Όμ λ₯Ό μ μνλ€.
νλμ λλ‘λ μ¬λ¬ μ¬λμ κΈ°μ΅μ λμμ κ΄λ¦¬ν μ μλ―, static λ³μ νλλ‘λ λΆμ‘±νλ€. ν΄κ²°μ±
μ βκΈ°μ΅μ λͺ©λ‘βμ λ§λλ κ²μ΄λ€.
νμΌ λμ€ν¬λ¦½ν°(FD)λ₯Ό μ΄μ μΌμ, κ° μ΄μ μ λ§λ backup λ°μ΄ν°λ₯Ό μ μ₯νλ λ°°μ΄(static char *backup[OPEN_MAX])μ΄λ μ°κ²° 리μ€νΈλ₯Ό νμ©νλ€.
GNLμ΄ νΉμ fdμ ν¨κ» νΈμΆλλ©΄, μ°λ¦¬λ κΈ°μ΅μ λͺ©λ‘μμ ν΄λΉ fdμ λ§λ κΈ°μ΅μ κΊΌλ΄ μμ
μ μ΄μ΄κ°λ€λ κ²μ ꡬ쑰ν νλ κ²μ΄ κ΄κ±΄μ΄μλ€.
π€ μ±μ°° λ° λ°°μ΄ μ (Reflection & Lessons Learned)
GNLμ λμκ² β보μ΄μ§ μλ κ²μ λ€λ£¨λ λ²βμ κ°λ₯΄μ³μ€¬λ€.
- μν κ΄λ¦¬μ λ³Έμ§: νμΌ μ μΆλ ₯μ λμ΄, βμνβλΌλ μΆμμ μΈ κ°λ μ μ΄λ»κ² μ½λ λ 벨μμ ꡬ체ννκ³ μ μ§νλμ§ κΉμ΄ μ΄ν΄νκ² λμλ€. μ΄λ λμ€μ μΉ μλ²κ° μλ§μ ν΄λΌμ΄μΈνΈμ μ°κ²° μνλ₯Ό κΈ°μ΅νκ±°λ, UI νλ μμν¬κ° μ»΄ν¬λνΈμ μ΄μ μνλ₯Ό κΈ°μ΅νλ λ± λͺ¨λ νλ‘κ·Έλλ°μ κ·Όκ°μ΄ λλ μ리μλ€. μ΄μ λ μ λ§ λ€μν λꡬλ, κ°λ μ΄ μκ³ , μ¬μ€ μ‘°κΈ λ κ³°κ³°ν μκ°ν΄λ³΄λ©΄ βstaticβμ΄ λ΄λΆμ λΉμ°ν λ Ήμ μκ² μ§λ§, μ΄μ λ λ€μ ꡬμ(β¦.) λ°©λ²μμ μμΌ λλΌκΈ΄νλ€. κ·Έλ¬λ κ²°κ΅ μ΅μ νκ° νμνκ³ , λ°μ΄ν°λ₯Ό λ κ³ μμΌλ‘, λ λΉ λ₯΄κ² μ²λ¦¬ν΄μΌνλ€λ©΄ μ΄μ©λ©΄ λ€μ λμ§μ΄λΌ κΈ°νκ° μ€μ§ μμκΉ, κ·Έλ κ² μκ°ν΄λ³Έλ€.
staticμ μ² ν:staticμ λ¨μν CμΈμ΄μ ν€μλκ° μλμλ€. ν¨μμ μλͺ μ£ΌκΈ°λ₯Ό μ΄μνμ¬ λ°μ΄ν°λ₯Ό 보쑴νλ, CμΈμ΄κ° μ 곡νλ κ°μ₯ μμμ μ΄λ©΄μλ κ°λ ₯ν μν κ΄λ¦¬ λꡬμμ κΉ¨λ¬μλ€. κ·Έλλ μΌλ§λ λΉ λ₯Έκ°? μ΄κ±Έ κΈ°λ°μΌλ‘ κ½€λ νΈλ€κ°μ λ¨μλ(β¦) κΈ°μ΅μ΄ λλ€.- λλ²κΉ κ³Όμ μ²μ ν μ¬ν¬: λμμ΄ ν°μ§λ λ©λͺ¨λ¦¬ λμμ μΈκ·Έν΄μ λλ₯Ό μ’μ μμΌ°μ§λ§, λμμ λ©λͺ¨λ¦¬μ ν λΉκ³Ό ν΄μ μ νλ¦μ μ§μνκ² μΆμ νλ μΈλ΄μ¬κ³Ό λ¬Έμ ν΄κ²° λ₯λ ₯μ κΈΈλ¬μ£Όμλ€. κ·Έκ² ν΅μ¬μ΄κΈ°λ νλ€. νΉν 보λμ€λ₯Ό νκ² λλ©΄, FD μ κ΄λ¦¬κ° λ³λ ¬λ‘ μ§νλλλ°, μ‘°κ±΄μ΄ μΆκ°λ μλ‘ λΉμ°ν κΈ°μ‘΄ λ΄μ©μ λκ³ , λ€λ₯Έ λ΄μ©μ μ°Ύμμ¨λ€λ μμ μ΄ μ΄μ λ λ¨Έλ¦Ώμμ κ·Έλ €μ§κΈ°μ μ΄λμ λ μ‘μμΌ νλκ°? λ₯Ό κΈ°μ΅νμ§λ§, κ·Έλ μ λ§ νλ€μλ€.
get_next_lineμ ν μ€μ λ¬Έμ₯μ μ½μ΄λΈλ€λΌκ³ μ½κ² μ΄μΌκΈ΄ νμ§λ§, ν΅μ¬μ μνλ₯Ό μ μ₯νκ³ , μ΄λ€ λΉμ¦λμ€ λ‘μ§μ κ±°μΉκ³ , λ κ±°κΈ°μ μ¬λ¬ νμΌμ λ€λ£¬λ€λ©΄ μ΄λ€ κ³Όμ μΌλ‘ μμ
μ μλ€ κ°λ€ ν μ μλμ§, κ·Έ λ
Όλ¦¬μ λ‘μ§μ΄ λμ§λ₯Ό μ€μ§μ μΌλ‘ λ°°μ°λ κΈ°νμλ€κ³ μκ°νλ€.
