1. External Functions
pipexλ₯Ό ꡬννλλ° μμ΄μ νμ©λ ν¨μλ€μ μλμ κ°λ€.
β’
open
β’
close
β’
read
β’
write
β’
malloc
β’
free
β’
access
β’
unlink
β’
fork
β’
wait
β’
waitpid
β’
dup
β’
dup2
β’
pipe
β’
execve
β’
perror
β’
strerror
β’
exit
μ΄ μ€μμ μ΄μ μ μμ£Ό μ¬μ©νλ open, close, read, write, malloc, freeλ μκ°λ₯Ό μλ΅ν κ²μ΄λ€. λν perror, strerror, exitμ λν΄μλ miniRT κ³Όμ λ₯Ό μκ°ν λ μ΄λ―Έ μμλ³Έ μ μ΄ μλ€. λ°λΌμ perror, strerror, exitμ λν΄μλ μλ λ§ν¬μ External Functionsλ₯Ό μ°Έκ³ νμ.
μ΄λ² κΈμμλ access, unlink, fork, wait, waitpid, dup, dup2, pipe, execveλ§μ μμλ³Ό κ²μ΄λ€. μ€λͺ
λ λ΄μ©μλ Errorμ λν μκΈ°κ° μ’
μ’
λμ¨λ€. λ°λΌμ μ λ§ν¬μ Errorμ λν λ΄μ©μ κΌ λ¨Όμ μ½κ³ μ€κΈΈ λ°λλ€. λ§ν¬μ κΈμ΄ λ무 κΈΈλ€λ©΄ μ μ΄λ errnoμ λν΄μλΌλ μ΄ν΄νλ κ²μ κΆνλ€.
1) access
1. μμ‘΄μ±
#include <unistd.h>
C
볡μ¬
2. ν¨μ μν
int access(const char *path, int mode);
C
볡μ¬
3. ν¨μ μ€λͺ
access ν¨μλ pathμ ν΄λΉνλ νμΌμ modeμ λ°λΌμ νμΈμ νκ² λλ€. pathμλ μΌλ° νμΌ μΈμ μ¬λ³Όλ¦ λ§ν¬, λλ ν 리 λ±μ ν¬ν¨νμ¬ λͺ¨λ νμΌμ μΈμλ‘ μ¬μ©ν μ μλ€. modeλ <unistd.h>μ 맀ν¬λ‘λ₯Ό ν΅ν΄ κ°λ€μ΄ μ μλμ΄ μλ€. access ν¨μλ μΈμλ‘ λ°μ modeμ λ§μ‘±νλ©΄ 0μ λ°ννκ³ , κ·Έλ μ§ μμΌλ©΄ -1μ λ°ννλ€.
μ κ·Έλ¦Όμμ λ³Ό μ μλ―μ΄, modeλ₯Ό ν΅ν΄μ νμΌμ μ‘΄μ¬ μ 무 λ° νμΌμ κΆνμ νμΈν μ μλ€. modeλ‘ μ£Όμ΄μ§ κ°λ€μ λΉνΈλ₯Ό μ¬ννΈ ν κ°λ€λ‘ μ μλμκΈ° λλ¬Έμ Maskλ‘μ¨ μ΄μ©λ μ μλ€. λ°λΌμ νμΌμ μ‘΄μ¬ μ 무μ λμμ νμΌμ μ€ν κΆνμ΄ μλμ§ λμμ νμΈνκ³ μΆλ€λ©΄, | λΌλ OR λΉνΈ μ°μ°μ μ΄μ©νμ¬ ν λ²μ κ²μ¬νλ κ²μ΄ κ°λ₯νλ€. μλ₯Ό λ€μ΄, mode = F_OK | X_OK;μ κ°μ΄ λκ³ access ν¨μμ μΈμλ‘ modeλ₯Ό μ£Όκ² λλ©΄ νμΌμ μ‘΄μ¬ μ 무μ νμΌμ μ€ν κΆνμ λμμ νμΈν μ μλ€. λ¨, |λ₯Ό ν΅ν΄ λμμ κ²μ¬νλ €λ μ‘°κ±΄λ€ μ€μ νλλΌλ λ§μ‘±νμ§ μλλ€λ©΄ λ°ν κ°μΌλ‘ -1μ λ°κ² λλ―λ‘, |λ μ¬λ¬ 쑰건μ λμμ λ§μ‘±ν΄μΌ νλ κ²½μ°μλ§ μ¬μ©νλλ‘ νλ€.
cd, exitκ³Ό κ°μ΄ Shellμ Built-In λͺ
λ Ήμ΄λ₯Ό μ μΈνκ³ , νμΌλ‘ μ μ§ λλ λͺ
λ Ήμ΄λ€μ exec κ³μ΄μ ν¨μλ₯Ό μ΄μ©νμ¬ μ€ννκΈ° μ μ access ν¨μλ₯Ό ν΅ν΄ μ νμ μΌλ‘ νμΌμ λν κ²μ¬λ₯Ό μνν μ μλ€.
4. μμ
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int mode;
mode = 0;
mode |= F_OK;
if (!access("test.txt", mode))
printf("File is existing\n");
else
printf("File is not existing\n");
mode &= 0;
mode |= X_OK;
if (!access("test.txt", mode))
printf("File is executable\n");
else
printf("File is not executable\n");
return (0);
}
C
볡μ¬
2) unlink
1. μμ‘΄μ±
#include <unistd.h>
C
볡μ¬
2. ν¨μ μν
int unlink(const char *path);
C
볡μ¬
3. ν¨μ μ€λͺ
unlink ν¨μλ νμΌμ μμ ν λ μ¬μ©λλ€. κ°λ¨νκ²λ νμΌμ μμ μ΄μ§λ§, μ ννκ²λ νλ λ§ν¬λ₯Ό λλλ° μ΄μ©λλ€. λ°λΌμ unlink ν¨μλ₯Ό μ΄ν΄νκΈ° μ μ νλ λ§ν¬μ μ¬λ³Όλ¦ λ§ν¬μ λν΄μ μ΄ν΄ν νμκ° μλ€.
μΌλ°μ μΌλ‘ λ§νλ νμΌμ μ€μ λ‘ λμ€ν¬ μμ μμΉν λ°μ΄ν°μ λΆκ³Όνλ€. μ¦, νμΌμ μμ±νκ³ μμ νλ€λ κ°λ
μ λμ€ν¬ μμ λ°μ΄ν°λ₯Ό μμ±νκ³ μμ νλ€λ κ²κ³Ό μΌλ§₯μν΅νλ€. κ·Έλ¦¬κ³ νμΌμ΄λΌκ³ λΆλ¦¬λ μ΄ λ°μ΄ν°λ€μ μ λμ€ κ³μ΄μ μ΄μ체μ μμ λͺ¨λ inodeλ‘ κ΄λ¦¬λλ€. inodeμλ νμΌμ κΆν, νν, κ³ μ λ²νΈ, μμ μ λ° κ·Έλ£Ή, μλ³Έ λ°μ΄ν°μ μ£Όμ λ± νμΌμ λν λͺ¨λ κ²λ€μ΄ κΈ°λ‘λμ΄ μλ€. μ΄μ λν΄μ μ κ·Έλ¦Όμ ν΅ν΄ μ‘°κΈ λ μ νν μ΄ν΄ν μ μλ€. μ¦, inodeλ₯Ό ν΅ν΄ λ°μ΄ν°λ€μ λ³΄λ€ μ½κ² μ‘°μνκ³ κ΄λ¦¬ν μ μλ€λ κ²μ΄λ€. μ΄ λ μ¬μ©μλ λ°μ΄ν°λ₯Ό μ€ννκ±°λ μ½κ³ μ°λ λ± μ‘°μμ νκ³ μ νλ€λ©΄, νλ λ§ν¬λ₯Ό μ΄μ©νμ¬ inodeμ μ κ·Όνκ³ μνλ μμ
μ μννκ² λλ€. μ¦, μΌλ°μ μΌλ‘ μ¬μ©μ 곡κ°μμ νμΈν μ μλ νμΌλ€μ λͺ¨λ νλ λ§ν¬λΌκ³ λ³Ό μ μλ€.
μμμ νμΈν κ²μ²λΌ κΈ°λ³Έμ μΌλ‘ νμΌμ΄ μ‘΄μ¬νλ€λ κ²μ λμ€ν¬ μμ λ°μ΄ν°κ° μ‘΄μ¬νλ κ²μ΄κ³ , μ΄μ λν inodeκ° λ¬΄μ‘°κ±΄ μ‘΄μ¬ν¨κ³Ό λμμ inodeμ μ κ·Όν μ μλ νλ λ§ν¬λ₯Ό μ μ΄λ νλ μ΄μ κ°μ§κ³ μλ κ²μ μλ―Ένλ€. λ§μΌ inodeμ μ κ·Όν μ μλ νλ λ§ν¬κ° νλλ μκ² λλ©΄, μ΄κ²μ΄ 곧 νμΌμ μμ λ‘ μ΄μ΄μ§λ€.
κ·Έλ λ€λ©΄ κΈ°μ‘΄μ μ‘΄μ¬νκ³ μλ νλ λ§ν¬μ ln λͺ
λ Ήμ΄λ₯Ό μ΄μ©νλ©΄ μ΄λ»κ² λ κΉ? νλμ νμΌμ΄ μΆκ°μ μΌλ‘ μμ±λλ κ²μ λ³Ό μ μλλ°, μ¬μ©μκ° λ³΄κΈ°μλ λ³λμ νμΌμ΄ μμ±λ κ²μ²λΌ 보μ΄μ§λ§ μ€μ λ‘λ λμΌν inodeλ₯Ό κ°λ¦¬ν€λ νλ λ§ν¬μ λΆκ³Όνλ€. λ°μ΄ν°λ₯Ό μ°Έμ‘°νκ³ μλ inodeλ κ³ μ νκ³ , νλ λ§ν¬λ€μ΄ λͺ κ°κ° μλ μμ κ·Έλ¦Όκ³Ό κ°μ΄ λͺ¨λ λμΌν inodeλ₯Ό μ°Έμ‘°νκ² λλ€. μ€μ λ‘ λμ€ν¬ μμ μ‘΄μ¬νλ λ°μ΄ν°λ₯Ό μμ νκ² λλ©΄, λͺ¨λ νλ λ§ν¬λ€μ΄ μν₯μ λ°λ μ΄μ κ° μ΄ λλ¬Έμ΄λ€. κ·Έλ¦¬κ³ λμΌν inodeλ₯Ό μ°Έμ‘°νκ³ μλ νλ λ§ν¬κ° λ€μ μ‘΄μ¬νμ¬λ ν¬κΈ°λ κ³ μ νκ² μ μ λλ€. νλ λ§ν¬μ λνμ μΈ μλ νμ¬ λλ ν 리λ₯Ό μλ―Ένλ .μ μμ λλ ν 리λ₯Ό μλ―Ένλ ..μ΄ μλ€.
μ¬λ³Όλ¦ λ§ν¬λ ln λͺ
λ Ήμ΄μ -s μ΅μ
μ μ΄μ©νμ¬ μμ±ν μ μλλ°, μ΄λ₯Ό μ΄μ©νλ©΄ νλ λ§ν¬μ λμΌνκ² νμΌμ΄ μΆκ°μ μΌλ‘ μμ±λλ κ²μ λ³Ό μ μλ€. νμ§λ§ inodeλ₯Ό μ‘°μ¬ν΄λ³΄λ©΄ νλ λ§ν¬μλ λ¬λ¦¬ λ³λμ inodeλ₯Ό μ°Έμ‘°νλ κ²μ νμΈν μ μλ€. μ¦, μ¬λ³Όλ¦ λ§ν¬λ₯Ό ν΅ν΄ μμ±λ νμΌμ νλ λ§ν¬μ λ¬λ¦¬ νλ λ§ν¬μ λν inodeλ₯Ό μ°Έμ‘°νμ§ μλλ€. μ΄μ κ°μ μν©μ μ κ·Έλ¦Όμ ν΅ν΄μ μ μ μλ―μ΄, μ¬λ³Όλ¦ λ§ν¬λ λ³λμ inodeλ₯Ό κ°κ³ μκ³ λμ€ν¬ μμ λ³λμ λ°μ΄ν°λ₯Ό μ μ§νκ³ μμΌλ©° λμ€ν¬ μμ λ°μ΄ν°λ κ·Έμ νλ λ§ν¬μ inodeλ₯Ό μ°Έμ‘°νλλ‘ μ£Όμλ§μ κ°μ§κ³ μμ λΏμ΄λ€. μ΄ λλ¬Έμ μ¬λ³Όλ¦ λ§ν¬κ° λ°λ‘ κ°κΈ°μ κ°μ΄ μλν μ μμΌλ©° νλ λ§ν¬μ λ¬λ¦¬ λ³λμ ν¬κΈ°λ₯Ό κ°λ κ²μ΄λ€. μ¬λ³Όλ¦ λ§ν¬λ‘ μμ±λ νμΌμ μ΄λ€ νλ λ§ν¬λ₯Ό μ°Έμ‘°νλ ν¬μΈν° λ§ν¬μ΄λ©΄μ, λμμ νλμ νλ λ§ν¬μ΄λ€.
μμμ unlink ν¨μλ νλ λ§ν¬λ₯Ό λλλ° μ΄μ©λλ€κ³ νλλ°, μ΄λ νλ λ§ν¬μ μ΄λ¦μ μμ νλ©΄μ inodeλ₯Ό μ°Έμ‘°νκ³ μλ νλμ νλ λ§ν¬λ₯Ό λλ κ²μ΄λ€. μλ₯Ό λ€μ΄ μ κ·Έλ¦Όκ³Ό κ°μ΄ μ¬μ©μμ 곡κ°μ a, b, cκ° μκ³ , 3κ°μ νλ λ§ν¬λ λͺ¨λ λμΌν inodeλ₯Ό μ°Έμ‘°νκ³ μλ€κ³ ν΄λ³΄μ. λ§μ½ unlinkμ path μΈμλ‘ aλΌλ νλ λ§ν¬λ₯Ό μ£Όκ² λλ©΄, μ¬μ©μμ 곡κ°μμ aλ μμ λμ§λ§ μ¬μ ν κ·Έ νμΌμ μ‘΄μ¬νκ³ μλ€. μ¦, μ¬μ©μκ° λ³΄μμ λλ νμΌμ μμ νλ κ²μ²λΌ 보μ΄μ§λ§ νμΌμ μμ ν μμ νκΈ° μν΄μ inodeλ₯Ό μ°Έμ‘°νλ λͺ¨λ νλ λ§ν¬λ₯Ό λμ΄μΌλ§ λΉλ‘μ νμΌμ΄ μμ λλ€. μ΄μ κ°μ λμμ μ λμ€μ rm λͺ
λ Ήμ΄μ λμΌνλ€. rm λͺ
λ Ήμ΄μ λμμ΄ μΌλ° νμΌμ΄λΌλ©΄ μ΄λ unlink ν¨μμ λμΌνκ² μλνκ³ , λμμ΄ λλ ν 리λΌλ©΄ μ΄λ rmdir λͺ
λ Ήμ΄μ λμΌνκ² μλνλ€.
νμΌμ μμ λΌλ κ°λ
κ³Ό νλ λ§ν¬λ₯Ό λλλ€λ κ²μ λν μ νν μ°¨μ΄λ₯Ό μ΄ν΄νκΈ° μν΄ μ€λͺ
μ΄ κΈΈμλλ°, μ¬νΌ μ¬μ©μκ° λ³΄κΈ°μλ unlinkμ λμμ΄ κ³§ μ¬μ©μ 곡κ°μ μ‘΄μ¬νλ νμΌμ μμ μ λμΌνλ€κ³ λ³Ό μ μλ€. unlinkμ λ°ν κ°μ΄ 0μ΄λΌλ©΄ μ μμ μΌλ‘ νλ λ§ν¬λ₯Ό λμ κ²μ΄κ³ , μ μμ μΌλ‘ λμνμ§ λͺ»νμ λλ -1μ΄ λ°νλλ€.
4. μμ
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int i;
i = 0;
while (++i < argc)
{
if (!access(argv[i], F_OK))
{
if (!unlink(argv[i]))
printf("File is unlinked\n");
else
printf("File is not unlinked\n");
}
else
printf("File is not existing\n");
}
return (0);
}
C
볡μ¬
3) fork
1. μμ‘΄μ±
#include <unistd.h>
C
볡μ¬
2. ν¨μ μν
pid_t fork(void);
C
볡μ¬
3. ν¨μ μ€λͺ
νμ¬ μ€ν μ€μΈ νλ‘μΈμ€μμ μμ νλ‘μΈμ€λ₯Ό μμ±νλ€. μ΄μ λ°λΌ νμ¬ μ€ν μ€μΈ νλ‘μΈμ€λ μμ νλ‘μΈμ€λ₯Ό κ°κ³ μλ λΆλͺ¨ νλ‘μΈμ€κ° λλ€. μμ±λ μμ νλ‘μΈμ€λ λΆλͺ¨ νλ‘μΈμ€μ μμ ν λκ°μ ννλ‘ μμ±μ΄ λλλ°, μ΄λ 곧 λΆλͺ¨ νλ‘μΈμ€μ λ©λͺ¨λ¦¬μ μνλ₯Ό κ·Έλλ‘ κ°λλ€λ κ²μ μλ―Ένλ€. μ¦, λΆλͺ¨ νλ‘μΈμ€μ λ©λͺ¨λ¦¬ μ£Όμ 곡κ°μ μΌκ΄μ μΌλ‘ 볡μ¬νμ¬ μ΄λ₯Ό μμ νλ‘μΈμ€μκ² ν λΉνκ² λκ³ , PC (Program Counter) μμ 볡μ¬λμ΄ μμ νλ‘μΈμ€λ fork ν¨μ νΈμΆ μ΄νλΆν° Contextλ₯Ό κ°κ² λλ€.
PC (Program Counter)?
PC λΌλ κ²μ CPUμ κ°μ μ€μ μ²λ¦¬ μ₯μΉ λ΄λΆμ λ μ§μ€ν° μ€μ νλλ‘μ¨ νμ¬ μ²λ¦¬ μ€μΈ Instructionμ λ°λ‘ λ€μ Instructionμ μ£Όμλ₯Ό κ°κ³ μλ€. μ¦, μ€νλ Instructionμ μμΉλ₯Ό μκ³ μκΈ° λλ¬Έμ Instruction Pointer λΌκ³ λΆλ¦¬κΈ°λ νλ€. μ¬κΈ°μ λ§νλ Instructionμ΄λ C μΈμ΄μ μ½λ ν μ€μ λ§νλ κ²μ΄ μλλΌ, κΈ°κ³μ μΌλ‘ μ²λ¦¬λλ κΈ°κ³μ΄ ν ꡬ문μ λ§νλ€.
μμ forkλ₯Ό μλ‘ λ€λ©΄, forkλ₯Ό μ²λ¦¬νλλ° μꡬλλ κΈ°κ³μ΄ λ¬Άμμ΄ μμν
λ° μ΄λ₯Ό λ§μΉκ² λλ©΄ PCλ fork λ€μμ μ€νλ ꡬ문μ 첫 κΈ°κ³μ΄μ μμΉλ₯Ό κ°κ³ μκ² λλ€. μμ νλ‘μΈμ€λ PC μμ 볡μ¬νμ¬ μμ±λκΈ° λλ¬Έμ PCκ° κ°κ³ μλ μ£Όμμ ν΄λΉνλ InstructionλΆν° Fetchνμ¬ μ€ννλ€.
μ΄μ²λΌ μμ νλ‘μΈμ€λ₯Ό κ°κ² λμμ λ forkμ λ°ν κ°μΌλ‘ λΆλͺ¨ νλ‘μΈμ€μκ² ν λΉλλ κ°κ³Ό μμ νλ‘μΈμ€μκ² ν λΉλλ κ°μ΄ μλ‘ λ€λ₯΄λ€. λΆλͺ¨ νλ‘μΈμ€μλ μμ νλ‘μΈμ€μ pid κ°μ΄ forkμ λ°ν κ°μΌλ‘ μ€μ λκ³ , μμ νλ‘μΈμ€μλ 0μ΄λΌλ κ°μ΄ forkμ λ°ν κ°μΌλ‘ μ€μ λλ€. λ§μΌ λΆλͺ¨ νλ‘μΈμ€μμ forkλ₯Ό μννμ λ μ μμ μΌλ‘ forkκ° λμ§ μλλ€λ©΄ -1μ΄ λ°νλλ€. λ°λΌμ μ΄μ λν μλ¬ μ²λ¦¬λ₯Ό λ³λλ‘ ν΄μ£Όμ΄μΌ νλ€.
4. μμ
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int global;
int main(void)
{
int automatic;
int *heap;
pid_t pid;
global = 10;
automatic = 10;
heap = (int *)malloc(sizeof(int));
if (!heap)
return (1);
*heap = 10;
pid = fork();
if (pid == -1)
{
free(heap);
return (1);
}
else if (!pid)
{
printf("Child: Before operations -> %d (Global), %d (Automatic), %d (Heap)\n", global, automatic, *heap);
global += 10;
automatic += 10;
*heap += 10;
printf("Child: After operations -> %d (Global), %d (Automatic), %d (Heap)\n", global, automatic, *heap);
}
else if (pid)
{
printf("Parent: Before operations -> %d (Global), %d (Automatic), %d (Heap)\n", global, automatic, *heap);
global += 20;
automatic += 20;
*heap += 20;
printf("Parent: After operations -> %d (Global), %d (Automatic), %d (Heap)\n", global, automatic, *heap);
}
free(heap);
return (0);
}
C
볡μ¬
μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€μ λ©λͺ¨λ¦¬ 곡κ°μ΄ λ³λλ‘ κ΅¬μ±λλ€λ κ²μ μμ κ°μ μ½λλ₯Ό μ€νν¨μΌλ‘μ¨ μ½κ² μ μ μλ€. λ©λͺ¨λ¦¬ 곡κ°μ΄ λ³λμ΄λ―λ‘ μμ νλ‘μΈμ€μμμ μ¦κ° μ°μ° κ²°κ³Όμ λΆλͺ¨ νλ‘μΈμ€μμμ μ¦κ° μ°μ°μ κ²°κ³Όκ° λ€λ₯Έ κ²μ μ£Όμ΄μ§ κ·Έλ¦Όμ²λΌ νμΈν μ μλ€.
μ μ΄μ νλ‘μΈμ€κ° μ΄μ체μ λ‘λΆν° ν λΉλ°μ λ©λͺ¨λ¦¬λ Shared Memory κΈ°λ²μ μ¬μ©νμ§ μλ μ΄μ λ€λ₯Έ νλ‘μΈμ€μ 곡μ λ μ μλ λ
립μ±μ 보μ₯λ°κΈ° λλ¬Έμ λ³λμ 곡κ°μ΄λΌλ κ²μ μ¦λͺ
νκΈ° μν΄ κ΅³μ΄ μμ κ°μ μ€νμ νμ§ μμλ λλ€.
#include <stdio.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid == -1)
return (1);
else if (!pid)
{
printf("Child: I got a pid %d internally\n", pid);
usleep(100000);
printf("Child: Exiting with Code 0\n");
}
else if (pid)
{
printf("Parent: I have a Child which pid is %d\n", pid);
printf("Parent: Exiting with Code 0\n");
}
return (0);
}
C
볡μ¬
μ£Όμ΄μ§ μμλ₯Ό μ€νν΄λ³΄λ©΄, usleepμΌλ‘ 0.1μ΄κ° μμ νλ‘μΈμ€λ₯Ό Sleep μνλ‘ λ§λ€κΈ° λλ¬Έμ λΆλͺ¨ νλ‘μΈμ€κ° λ¨Όμ μ’
λ£νλ κ²μ λ³Ό μ μλ€. μ μ체μμ μ€νλ νλ‘μΈμ€λ λΆλͺ¨ νλ‘μΈμ€μ΄κΈ° λλ¬Έμ λΆλͺ¨ νλ‘μΈμ€μ μ’
λ£λ§ κΈ°λ€λ¦¬κ² λκ³ , λΆλͺ¨ νλ‘μΈμ€μ μ’
λ£μ λμμ μμ μλ‘μ΄ ν둬ννΈλ₯Ό μΆλ ₯μν€λ κ²μ λ³Ό μ μλ€. λ°λΌμ νλ‘κ·Έλ¨μ΄ λ§μΉ λ€μ λ€λ¦κ² μμ νλ‘μΈμ€κ° μΆλ ₯ν κ΅¬λ¬Έμ΄ μλ‘μ΄ ν둬ννΈ μ΄νμ λνλκ² λλ€. μμ νλ‘μΈμ€μ μμ
μ λ§μΉ λκΉμ§ λΆλͺ¨ νλ‘μΈμ€κ° μ΄λ₯Ό κΈ°λ€λ¦¬κ² νκΈ° μν΄μ wait νΉμ waitpidλ₯Ό μ΄μ©ν΄μΌ νλ€. μ΄μ κ°μ ν¨μλ€μ ν΅ν΄ λ©ν° νλ‘μΈμ± νλ‘κ·Έλ¨μ λν΄ λ³΄λ€ μ¬λ μκ² μ΄ν΄ν μ μλ€. μ΄μ΄μ§λ νλͺ©μμ wait ν¨μλΆν° μ΄ν΄ν΄λ³΄μ.
4) wait
1. μμ‘΄μ±
#include <sys/wait.h>
C
볡μ¬
2. ν¨μ μν
pid_t wait(int *status);
C
볡μ¬
3. ν¨μ μ€λͺ
wait ν¨μλ μμ νλ‘μΈμ€μ μ’
λ£λ₯Ό λΆλͺ¨ νλ‘μΈμ€μμ κΈ°λ€λ¦°λ€λ κ°λ
μΌλ‘ κ°λ¨ν μ΄ν΄ν μ μλ€. μ΄μ fork ν¨μμ μμ λ₯Ό 보면 μμ νλ‘μΈμ€λ 0.1μ΄λμ Sleep μνκ° λμ΄ λΆλͺ¨ νλ‘μΈμ€κ° λ¨Όμ μ’
λ£λμλλ°, μ΄ λ μμ νλ‘μΈμ€μ ppidλ 1μ΄ λλ©΄μ κ³ μ νλ‘μΈμ€κ° λλ€. μ΄μ κ°μ νμμ λ°©μ§ν λ μ¬μ©λλ κ²μ΄ wait ν¨μμ΄λ€. wait ν¨μλ₯Ό μ΄μ©νκ² λλ©΄ λΆλͺ¨ νλ‘μΈμ€λ μμ νλ‘μΈμ€κ° μ’
λ£λ λκΉμ§ Sleep μνλ‘ κΈ°λ€λ¦¬κ² λλ©°, μμ νλ‘μΈμ€κ° μ’
λ£λμμ λ λΉλ‘μ wait ν¨μ μ΄νμ ꡬ문μ λΆλͺ¨ νλ‘μΈμ€κ° μ²λ¦¬ν μ μκ² λλ€. κ·Έλ λ€λ©΄ μμ νλ‘μΈμ€λ₯Ό κΈ°λ€λ¦¬μ§ μμλ λλ μν©μμλ wait ν¨μλ₯Ό μ°μ§ μμλ λλ κ²μΌκΉ? μ΄μ λν λ΅μ μλμ μμμμ μ°Ύμλ³Ό κ²μ΄λ€. κ·Έ μ μ wait ν¨μμ μκ·Έλμ²μ λν΄μ λ¨Όμ μμ보μ.
μμ νλ‘μΈμ€κ° mainλ¬Έμ return νΉμ exitμ ν΅ν΄ λͺ
μλ μ’
λ£ μ½λμ μν΄μ (μ μ μ’
λ£λ λΉμ μ μ’
λ£λ ) μ’
λ£λλ©΄ wait ν¨μμ λ°ν κ°μ μμ νλ‘μΈμ€μ pidκ° λκ³ , κ·Έλ μ§ μκ³ μμ νλ‘μΈμ€κ° μκ·Έλμ μν΄ μ’
λ£λλ©΄ errnoκ° EINTRλ‘ μ€μ λλ©΄μ -1μ λ°ννλ€. μ΄ λ wait ν¨μμ μΈμλ‘ λ°μ statusλ μμ νλ‘μΈμ€κ° μ’
λ£λλ©΄μ λ°νν λ€μν μ 보λ€μ κΈ°λ‘νκ² λλ€. μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€μ λ©λͺ¨λ¦¬ 곡κ°μ΄ λ³λλ‘ μ μ§λκΈ° λλ¬Έμ statusλΌλ μΈμλ μμ νλ‘μΈμ€μκ² λμ΄κ°μ κΈ°λ‘λλ κ²μ΄ μλλΌ λ§ κ·Έλλ‘ μμ νλ‘μΈμ€κ° μ’
λ£λλ©΄μ λκΈ΄ μ 보λ€μ λΆλͺ¨ νλ‘μΈμ€κ° μ·¨νλ©΄μ μμ νλ‘μΈμ€μ μ’
λ£ μμ μ κΈ°λ‘λλ κ²μ΄λ€. wait ν¨μμμ μ¬μ©λλ statusλ waitpidμμ μ¬μ©λλ statusμ λμΌνλ―λ‘ μ‘°κΈ κ΅¬κ΅¬μ μ νλλΌλ μ§κ³ λμ΄κ°λ³΄μ.
pid_tλ Mac OS Xμ κ°μ Darwin μ΄μ체μ μμ __darwin_id_tλ‘ Aliasλμ΄ μλ€. pid_tλΏλ§ μλλΌ uid_t, gid_tμ κ°μ νμ
λ€λ μ΄μ ν΄λΉλλ©°, __darwin_id_tλ __uint32_tμ΄λ€.
statusμ κΈ°λ‘λλ μ 보λ€μ μ’
λ£ μ½λμ μκ·Έλμ΄λ€. μ¬λ¬ μ λ³΄κ° νλμ λ³μμ κΈ°λ‘λμλ€λ κ²μ λΉνΈλ₯Ό μ΄μ©νμ¬ κΈ°λ‘λμλ€λ κ²μ΄λ―λ‘, μ΄μ κ°μ μ 보λ₯Ό κ°κ° νμνκΈ° μν΄μ λ³λμ λ§μ€νΉ μμ
μ΄ νμνλ€. λ°λΌμ κ° μ 보λ€μ΄ μΌλ§νΌμ λΉνΈλ₯Ό μ΄μ©νλμ§ μ νν νκΈ° μν΄μ <sys/wait.h>λ₯Ό νμΈν νμκ° μλ€. μ κ·Έλ¦Όμ 보면 statusμ κΈ°λ‘λ μ 보λ€μ νμΈν μ μλλ‘ λ§€ν¬λ‘λ₯Ό ν΅ν΄ μ μλ κ²μ λ³Ό μ μλλ°, λ΄μ©μ λμΉμ§ μλλ‘ μ°¬μ°¬ν μ§μ΄λ³΄μ.
μ μ½λλ₯Ό μΌν 보μμ λ μ£Όλ‘ μ΄μ©λλ λΉνΈ μ°μ°μ 8κ°μ λΉνΈλ₯Ό μ¬νν
νλ μ°μ°μ΄λ©°, μ΄ λ λΉκ΅λ λ¨ 1λ°μ΄νΈλ§μ μννλ κ²μ μ μ μλ€. ν΄λΉ μ°μ°μ΄ 무μμ μν κ²μΈμ§λ μμ§κΉμ§ μ μ μμ§λ§, int κ°μ statusλ₯Ό μ΄μ©νμ λ κΈ°λ‘ μ체λ 2λ°μ΄νΈ λ΄μμ μ΄λ€μ§λ€λ κ²μ μ μΆν μ μλ€. (μ¬νν
νμ λ 1λ°μ΄νΈμ΄λ―λ‘ κΈ°μ‘΄ 1λ°μ΄νΈκΉμ§ μ΄ 2λ°μ΄νΈκ° λλ€.) μ΄μ©λλ 곡κ°μ΄ 2λ°μ΄νΈμμλ statusκ° intλ‘ μ΄μ©λλ μ΄μ λ 곧 μκ² λλ€.
λ°μ΄νΈ κ°μ΄ κ°κ³ μλ μ 보μ λν΄ μ κ·Έλ¦Όμ μ΄μ©νμ¬ νμ΄λ³΄λ©΄, statusμ 4λ°μ΄νΈ μ€μμ 2λ² indexμ λ°μ΄νΈλ μ’
λ£ μ½λλ₯Ό μλ―Ένκ³ 3λ² indexμ λ°μ΄νΈλ μκ·Έλμ μλ―Ένλ€. μ¦, μ’
λ£ μ½λμ μκ·Έλμ μ‘°ν©ν κ°μ΄ 곧 statusκ° λλλ° μ΄ λ μ΄μ©νλ μ°μ°μ΄ W_EXITCODEλΌλ 맀ν¬λ‘ ν¨μμ΄λ€. μμ νλ‘μΈμ€κ° μ’
λ£λλ©΄ W_EXITCODEλ₯Ό μ΄μ©νμ¬ λΆλͺ¨ νλ‘μΈμ€μ statusλ₯Ό κΈ°λ‘νκ² λκ³ , W_EXITCODEλ μ λμ€ μ€κ³ μ int νμ
μΌλ‘ μ΄μ©νλλ‘ λμ΄ μλ€. λ°λΌμ 2λ°μ΄νΈλ§μ μ΄μ©ν¨μλ statusκ° intλ‘ μ΄μ©λλ κ²μ΄λ€.
μ’
λ£ μ½λ λ° μκ·Έλμ λν κΈ°λ‘μ λΆκΈ°λ μ κ·Έλ¦Όκ³Ό κ°μ΄ λνλλ€. λ°ν κ°μ λν΄ μ€λͺ
ν λ μ΄μ§ μΈκΈνλλ‘ μ’
λ£ μ½λμ μν μ’
λ£μΈμ§, μκ·Έλμ μν μ’
λ£μΈμ§κ° status κΈ°λ‘μ μν₯μ λΌμΉκ² λλ€. μ’
λ£ μ½λμ μν μ’
λ£κ° λ°μνμ λμ statusλ₯Ό μμλ³Έ λ€ μκ·Έλμ μν μ’
λ£κ° λ°μνμ λμ statusλ₯Ό μμ보λλ‘ νμ.
μΌλ°μ μΌλ‘ νλ‘μΈμ€κ° μ μμ μ΄λ λΉμ μμ μ΄λ μκ·Έλ μμ΄ μ’
λ£λ₯Ό νκ² λλ©΄, μ’
λ£ μ½λκ° 2λ² indexμ λ°μ΄νΈκ° κΈ°λ‘λκ³ 3λ² indexμ λ°μ΄νΈλ μκ·Έλμ΄ μμΌλ―λ‘ 0μΌλ‘ μ±μμ§κ² λλ€. μ μ μ’
λ£λ₯Ό μλ―Ένλ 0μ μμ νλ‘μΈμ€κ° λ°ννκ² λλ©΄, λΆλͺ¨ νλ‘μΈμ€μμλ μ’
λ£ μ½λλ 0μ΄κ³ μκ·Έλλ 0μ΄λ―λ‘ status κ°μ 0μ΄ λλ€. λ°λλ‘ λΉμ μ μ’
λ£λ₯Ό μλ―Ένλ 0 μ΄μΈμ κ°μ μμ νλ‘μΈμ€κ° λ°ννκ² λλ©΄, status κ°μ΄ λΉμ μμ μΌλ‘ ν° κ°μ΄ λμ€λ κ²μ νμΈν μ μλλ° μ΄λ 3λ² indexμ λ°μ΄νΈκ° 0μΌλ‘ μ±μμ Έ μλ κ²μ κ³ λ €νμ§ μμμ κ·Έλ λ€. 0 μ΄μΈμ μ’
λ£ μ½λλ₯Ό λ°μμ λ μ΄λ₯Ό μ ννκ² μ·¨λνκΈ° μν΄μ μκ·Έλμ λν μ 보λ₯Ό λ°°μ ν΄μΌνλ―λ‘, 8κ°μ λΉνΈλ₯Ό μ€λ₯Έμͺ½μΌλ‘ μ¬νν
ν ν μ νν μ΅νμ 8κ°μ λΉνΈλ₯Ό μ·¨λνλ©΄ λλ€.
λͺ
μλ μ’
λ£ μ½λμ μν μ’
λ£
λ§μΌ νλ‘μΈμ€κ° μκ·Έλμ μν΄μ μ’
λ£λ₯Ό νκ² λλ©΄, μ΄λ ν¬κ² STOP μκ·Έλμ μν μ’
λ£μΈμ§ μ΄λ₯Ό μ μΈν μκ·Έλμ μν μ’
λ£μΈμ§μ λ°λΌ λλκ² λλ€. STOP μκ·Έλμ μν μ’
λ£μΈ κ²½μ°μλ CONT μκ·Έλμ ν΅ν΄ STOP μμ λΆν° μ΄μ΄μ μ€νν μ μμ§λ§ κ·Έ μΈμ μκ·Έλμ κ·Έλ μ§ μλ€λ μ μμ μ°¨μ΄κ° μλ€.
μ°μ STOP μκ·Έλκ³Ό CONT μκ·Έλμ λ€λ₯Έ μκ·Έλλ€κ³Ό λ¬λ¦¬ μκΈ° μμ μκ² ν΄λΉλλ μκ·Έλ λ²νΈλ₯Ό μ¬μ©νλλΌλ λ΄λΆμ μΌλ‘ 3λ² indexμ λ°μ΄νΈ κ°μ΄ 127λ‘ κ³ μ λλ€. μ΄ λ μ’
λ£ μ½λκ° κΈ°λ‘λλ 2λ² indexμ λ°μ΄νΈκ° 곧 μκΈ° μμ μκ² ν΄λΉλλ μκ·Έλ λ²νΈλ‘ μ±μμ§λ€. CONT μκ·Έλμ 보λ΄λ κ²½μ°μλ SIGCONTμ ν΄λΉνλ 19κ° μ±μμ§κ³ , STOP μκ·Έλμ 보λ΄λ κ²½μ°μλ SIGSTOPμ ν΄λΉνλ 17μ΄ μ±μμ§κ² λλ€. STOP μκ·Έλμ ν΄λΉνλ 17κ³Ό CONT μκ·Έλμ ν΄λΉνλ 19μ 3λ² indexμ λ°μ΄νΈμ μ΄μ©νλ©΄ νΈν ν
λ°, κ·Έλ κ² νμ§ μλ μ΄μ λ λ μκ·Έλμ΄ μ κΈ°μ μΌλ‘ μ°κ²°λμ΄ μκΈ° λλ¬Έμ μ€μμΉμ on/offμ²λΌ λμνλλ‘ λ§λ€κΈ° μν¨μ΄λ€. νλμ νΉμ ν κ°μ μ ν΄λκ³ μ²λ¦¬νκ² λλ©΄ νλ‘κ·Έλ¨ μ
μ₯μμλ λ νΈν΄μ§λ€. (Mac OS Xμ μκ·Έλμ μ λμ€μ μκ·Έλμ λ°λ₯Έλ€. μμ€ν
λ§λ€ μκ·Έλμ΄ λ€λ₯Ό μ μμΌλ―λ‘ μ΄μ μ μνμ.)
μκ·Έλμ ν΄λΉνλ λ²νΈλ₯Ό μ΄μ©νλ©΄ μ΄λ€ μκ·ΈλμΈμ§ κ°κ° λΉκ΅λ₯Ό ν΄μΌνμ§λ§, λ λμ μμ²΄κ° μ κΈ°μ μΌλ‘ μ°κ²°λμ΄ μμΌλ―λ‘ λμΌν κ°μ μ΄μ©νλ©΄ ν λ²μ λΉκ΅λ§μΌλ‘ νΈνκ² μ²λ¦¬κ° κ°λ₯νλ€. νμ¬ νλ‘μΈμ€μ μνλ νλ‘κ·Έλ¨μ λ΄λΆμμ μ²λ¦¬νμ§ μμλ κ·Έ μνλ₯Ό μ μ μλ€.
μκ·Έλμ μν μ’
λ£ (STOP μκ·Έλ λ° CONT μκ·Έλ)
STOP μκ·Έλ μ΄μΈμ μκ·Έλμ ν΅ν΄μ νλ‘κ·Έλ¨μ΄ μ’
λ£λλ©΄, 2λ² indexλ₯Ό μλ―Ένλ μ’
λ£ μ½λλ 0μΌλ‘ μ±μμ§λ©° μκ·Έλμ ν΄λΉνλ κ°μ΄ 3λ² indexμ μ±μμ§κ² λλ€.
μκ·Έλμ μν μ’
λ£ (λλ¨Έμ§ μκ·Έλ)
waitμ μΈμλ‘ μ¬μ©λλ statusμ μ΄λ€ κ°λ€μ΄ κΈ°λ‘λκ³ , μ΄λ₯Ό μ΄λ»κ² μ·¨λνλμ§ μμ보μλ€. μ΄λ€μ μ΄μ©νμ¬ μ½λλ₯Ό μμ±ν λμλ νλμ κ²½μ°μ λν΄μλ§ μ²λ¦¬ν΄λλ κ²λ³΄λ€, WIFEXITED, WIFSIGNALED, WIFSTOPPED, WIFCONTINUEDλ₯Ό λͺ¨λ λΆκΈ° μ²λ¦¬νκ³ κ·Έμ λ°λΌ μ¬μ©λ κ°μ κ°κ° μ·¨λνμ¬ νλ‘κ·Έλ¨μ΄ μν©μ λ§κ² Contextλ₯Ό μ΄μ΄κ° μ μλλ‘ νλ κ²μ΄ λ°λμν λ°©ν₯μ΄λΌκ³ λ³Ό μ μλ€. μλμ κ°λ¨ν μ½λλ₯Ό λμλλ° μ΄μ κ°μ νμμΌλ‘ μν©μ λ°λΌ λΆκΈ°μ²λ¦¬λ₯Ό ν΄μ£Όλ©΄ λλ€.
λΆκΈ° μ²λ¦¬
wait ν¨μμ λ°ν κ°κ³Ό μ¬μ©λλ μΈμμ λν΄μ μμ보μμΌλ―λ‘, μλ μμλ₯Ό ν΅ν΄ ν¨μ μ€λͺ
μ΄κΈ°μ μΈκΈν λΆλΆμ λν΄μ μμ보λλ‘ νμ.
4. μμ
#include <stdio.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid == -1)
return (1);
else if (!pid)
printf("Child: I will be exited\n");
else
{
printf("Parent: I have a Child which pid is %d\n", pid);
while (1)
;
}
return (0);
}
C
볡μ¬
wait ν¨μλ₯Ό νΈμΆνλ μ£Όλ λͺ©μ μ μμ νλ‘μΈμ€μ μ’
λ£λ₯Ό κΈ°λ€λ¦¬λ κ² λ§κ³ λ, λΆλͺ¨ νλ‘μΈμ€μμ μμ±λ μμ νλ‘μΈμ€λ₯Ό μκ±°νλ λ° μλ€. μ£Όμ΄μ§ μ½λλ₯Ό μ€νν΄λ³΄λ©΄ λΆλͺ¨ νλ‘μΈμ€κ° 무ν 루νμ κ±Έλ € μκΈ° λλ¬Έμ μμ νλ‘μΈμ€κ° μΆλ ₯ ꡬ문μ μνν λ€μ λΆλͺ¨ νλ‘μΈμ€λ³΄λ€ λ¨Όμ μ’
λ£λλ κ²μ λ³Ό μ μλ€. μμ νλ‘μΈμ€κ° μ μμ μΌλ‘ λΆλͺ¨ νλ‘μΈμ€λ³΄λ€ λ¨Όμ μ’
λ£λμκΈ° λλ¬Έμ μ무 λ¬Έμ κ° μμ κ² κ°μ§λ§, μ£Όμ΄μ§ κ²°κ³Όλ₯Ό μ΄ν΄λ³΄λ©΄ μμ νλ‘μΈμ€κ° μ¬μ ν μ΄μμ μ’λΉ νλ‘μΈμ€λ‘ μ μ§λκ³ μλ κ²μ λ³Ό μ μλ€. μ’λΉ νλ‘μΈμ€λ μ΄λ¦μ²λΌ λΆλͺ¨ νλ‘μΈμ€κ° μ’
λ£λκΈ° μ κΉμ§λ νλ‘μΈμ€ ν
μ΄λΈμ λ¨μ μλ μνλ‘ μ μ§λλ€. λ°λΌμ λΆλͺ¨ νλ‘μΈμ€λ κΌ wait ν¨μλ₯Ό νΈμΆνλ©΄μ μμ νλ‘μΈμ€λ₯Ό μκ±°νμ¬ νλ‘μΈμ€ ν
μ΄λΈμμ μμ ν μλ¬΄κ° μμΌλ―λ‘ μ΄μ λ°λΌ μ£Όμ΄μ§ μ½λλ₯Ό μλμ κ°μ΄ wait ν¨μλ₯Ό νΈμΆνλλ‘ μμ ν΄μΌ νλ€.
μμ νλ‘μΈμ€κ° μ’
λ£λλ μ¦μ μ΄μ체μ μμλ μμ νλ‘μΈμ€μ λͺ¨λ μμμ λ¬Έμ μμ΄ νμνμ§λ§, μ΄ μμ μ νλ‘μΈμ€ ν
μ΄λΈμμ μμ νλ‘μΈμ€λ₯Ό μμ κΉμ§ ν΄λ²λ¦¬λ©΄ λΆλͺ¨ νλ‘μΈμ€λ μμ νλ‘μΈμ€μ λν μνμ λν΄ μ μ μλ μν©μ΄ λμ΄λ²λ¦°λ€. μ’λΉ νλ‘μΈμ€λ₯Ό λ μ΄μ λ μ΄ λλ¬Έμ΄λ€.
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
pid_t ret;
pid = fork();
if (pid == -1)
return (1);
else if (!pid)
printf("Child: I will be exited\n");
else
{
printf("Parent: I have a Child which pid is %d\n", pid);
ret = wait(NULL);
printf("Parent: %d Child has been retrieved\n", ret);
while (1)
;
}
return (0);
}
C
볡μ¬
5) waitpid
1. μμ‘΄μ±
#include <sys/wait.h>
C
볡μ¬
2. ν¨μ μν
pid_t waitpid(pid_t pid, int *status, int options);
C
볡μ¬
3. ν¨μ μ€λͺ
λ°ν κ° λ° statusλΌλ μΈμλ wait ν¨μμ λμΌνκΈ° λλ¬Έμ μ΄μ νλͺ©μμ wait ν¨μλΆν° μ½μ΄λ³΄κ³ μ€λ κ²μ κΆνλ€. waitpid ν¨μμμλ wait ν¨μμ λ¬λ¦¬ pid_t νμ
μΌλ‘ λ pidμ int νμ
μ optionμ μΆκ°μ μΌλ‘ μΈμλ‘ μ¬μ©νλ κ²μ λ³Ό μ μλ€. waitpidμ κΈ°λ₯ μ체λ wait ν¨μμ λμΌνκ², μ μμ μΌλ‘ μμ νλ‘μΈμ€μ μνλ₯Ό νλνκ³ μμμ μκ±°νκ³ λ°ννλλ° μλ€. κ·Έλ λ€λ©΄ μ΄λ€ κΈ°λ₯μ΄ λ€λ₯Έμ§ μΆκ°μ μΌλ‘ λ°μ μΈμλ€μ ν΅ν΄ μμλ³΄κ³ , waitpid ν¨μκ° λ§λ€μ΄μ§ μμλ₯Ό μμ보μ.
wait ν¨μμμ 보μλ μ΄μ μμλ€μ 보면 λΆλͺ¨ νλ‘μΈμ€μμ μμ±λ μμ νλ‘μΈμ€λ λ¨ 1κ°μλ€. λ§μ½ λΆλͺ¨ νλ‘μΈμ€μμ forkλ₯Ό ν΅ν΄ μμ±ν μμ νλ‘μΈμ€κ° 1κ°κ° μλλΌ μ¬λ¬ κ°λΌλ©΄, wait ν¨μλ₯Ό μ΄μ©νμ λ λΆλͺ¨ νλ‘μΈμ€μ Contextλ μμμ μμ νλ‘μΈμ€μ μ’
λ£λ₯Ό κΈ°λ€λ Έλ€κ° μκ±°νκ² λλ€. μ¦, νΉμ pidλ₯Ό κ°μ§ μμ νλ‘μΈμ€μ λν waitμ΄ λΆκ°λ₯νλ€λ κ²μ΄λ€. λ°λΌμ νΉμ νλ‘μΈμ€μ λν΄μ μνν μ μλλ‘ waitpid ν¨μμλ pidλΌλ μΈμλ₯Ό λ°κ² λμ΄ μλ€. μ΄ λ waitpidμ pidλ‘ -1μ΄λΌλ κ°μ μ£Όκ² λλ©΄, waitκ³Ό λμΌνκ² λμνμ¬ μμμ νλ‘μΈμ€λ₯Ό μκ±°νκ² λλ€.
λν wait ν¨μμ μμμμ λΆκ°νΌνκ² waitpidλ₯Ό μ¬μ©νλ κ²μ λ³Ό μ μμλλ°, waitpid ν¨μμλ νΉμ optionμ ν΅ν΄ wait ν¨μμμ μννμ§ λͺ»νλ κΈ°λ₯λ€μ μννλλ‘ λ§λ€ μ μλ€. μ΄μ μμλ₯Ό λ μ¬λ €λ³΄λ©΄ WUNTRACED, WCONTINUED, WNOHANGλ€μ΄ μμλλ°, μ΄λ€μ΄ 곧 waitpidμ optionμΌλ‘ μ¬μ©ν μ μλ κ°λ€μ΄λ€. ν΄λΉ κ°λ€μ λΉνΈ λ¨μλ‘ κ°μ΄ λ§€κ²¨μ Έ μκΈ° λλ¬Έμ, OR λΉνΈ μ°μ°μ ν΅ν΄ νλ²μ optionμΌλ‘ μ¬μ©ν μλ μλ€. (μ¬κΈ°μ μ μλ 3κ°μ optionμΈμλ WEXITED, WSTOPPED, WNOWAITμ΄ μμΌλ―λ‘ μ΄μ λν΄μ μ§μ μ°Ύμ보λλ‘ νμ.)
WUNTRACED β STOP μκ·Έλμ ν΅ν΄ μ€νμ λ©μΆ μμ νλ‘μΈμ€μ statusμ λν΄μ λ°ν
WCONTINUED β CONT μκ·Έλμ ν΅ν΄ μ€νμ μ¬κ°ν μμ νλ‘μΈμ€μ statusμ λν΄μ λ°ν
WNOHANG β μμ νλ‘μΈμ€μ μ’
λ£λ₯Ό κΈ°λ€λ¦¬μ§ μκ³ μ¦μ μμ νλ‘μΈμ€μ statusμ λν΄μ λ°ν
WNOHANGμ μ¬μ©νλ©΄ μμ νλ‘μΈμ€μ μ’
λ£λ₯Ό κΈ°λ€λ¦¬μ§ μκΈ° λλ¬Έμ WNOHANGμ μ¬μ©ν waitpid ν¨μμ νΈμΆ μμ μ μμ νλ‘μΈμ€κ° μ’
λ£λμμ μλ μκ³ κ·Έλ μ§ μμ μλ μλ€. λ κ²½μ°μλ waitpidμ λ°ν κ°μ΄ μλ‘ λ€λ₯΄λ€. WNOHANGμ μ¬μ©νκΈ° μ΄μ μ μμ νλ‘μΈμ€κ° μ’
λ£λ κ²½μ°μλ statusκ° μ¬λ°λ₯Έ κ°μ΄λ―λ‘, waitpidμ λ°ν κ°μ μμ νλ‘μΈμ€μ pidκ° λλ€. λ°λλ‘ μ΅μ
μ΄ μ¬μ©λμμ λ μμ νλ‘μΈμ€κ° μ’
λ£λμ§ μμ μνλΌλ©΄ statusκ° μ¬λ°λ₯΄μ§ μμ κ°μ΄ λλ―λ‘, waitpidμ λ°ν κ°μ 0μ΄ λλ€.
WUNTRACED λ° WCONTINUEDλ wait ν¨μμ μμμμ 보μλ κ²μ²λΌ STOP μκ·Έλ, CONT μκ·Έλμ λ°μ μμ νλ‘μΈμ€μ λν΄μλ statusλ₯Ό μ»μ΄μ¬ μ μλλ‘ λ§λ€μ΄μ€λ€. wait ν¨μλ μ΄μ κ°μ κΈ°λ₯μ μνν μ μμΌλ―λ‘ ν΄λΉ μν©μμλ waitpid ν¨μκ° μ μ©νκ² μ΄μ©λ μ μλ€.
μ€λ³΅λ μμλ μμ±νμ§ μμ μμ μ΄λ―λ‘ λ optionμ λν μμλ wait ν¨μμ μμλ₯Ό μ°Έκ³ νμ.
WNOHANGμ΄λΌλ optionμ wait ν¨μμ μμμμ μΈκΈνλλ‘ λκΈ° λ° λΉλκΈ°, Block λ° Non-Blockμ΄λΌλ κ°λ
μ΄ μ΄μ©λκΈ° λλ¬Έμ μ΄μ λν μ΄ν΄κ° μ μμ μΌλ‘ μꡬλλ€. WNOHANGμ μ¬μ©νμ§ μμμ λμ waitpidμ λμμ wait ν¨μμ ν¬κ² λ€λ₯΄μ§ μλ€. λΆλͺ¨ νλ‘μΈμ€μμ wait ν¨μλ₯Ό νΈμΆνκΈ° μ κΉμ§λ λΆλͺ¨ νλ‘μΈμ€μ μμ νλ‘μΈμ€ λ λ€ κ°μμ Contextλ₯Ό λ°λΌ λΉλκΈ°μ μΌλ‘ μ€νλκ³ , λΆλͺ¨ νλ‘μΈμ€μμ wait ν¨μλ₯Ό νΈμΆνμ λ 곧 λΆλͺ¨ νλ‘μΈμ€λ Block μνκ° λμ΄ μμ νλ‘μΈμ€μ μ’
λ£ μ κΉμ§ λ μ΄μμ Contextλ₯Ό μ΄μ΄κ°μ§ μλλ€. μ¦, wait ν¨μμ WNOHANGμ΄λΌλ optionμ΄ μλ waitpid ν¨μλ μμ νλ‘μΈμ€μ μ’
λ£λ₯Ό κΈ°λ€λ¦¬κΈ° μν΄ Block μνλ₯Ό μΌκΈ°νλλ‘ λμνλ€λ κ²μ΄ 곧 μμ μ΄λ€.
ν΄λΉ ν¨μλ€μ Blockμ΄λΌλ κΈ°λ³Έμ μΈ νΉμ±μ μλ§ μ΄μ©νλ©΄ μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€μ λμμ΄ μΌλ ¨μ λκΈ°μ νλ¦μΌλ‘ μ€νλλλ‘ λ§λ€ μ μλ€. λ°λΌμ Blockμ΄λΌλ νΉμ±μ μμλ₯Ό μ§μΌμ μνλμ΄μΌ νλ μ½λλ₯Ό λ§λ€μ΄μΌ νλ κ²½μ°μλ κ½€λ ν° μ₯μ μ΄ λλ€. νμ§λ§ κ³Όλνκ² Block μνλ₯Ό λ§λ€λ©΄ νλ‘κ·Έλ¨μ μ±λ₯ μ νλ‘ μ΄μ΄μ§ μ μκΈ° λλ¬Έμ μ£Όμν΄μΌ νλ€.
νλ‘κ·Έλ¨μ μμ±νλ€λ³΄λ©΄ μμμ μΈκΈν κ²μ²λΌ λκΈ°μ μΈ νλ¦μΌλ‘λ§ λμνλλ‘ λ§λ€μ§ μκ³ , Non-BlockμΌλ‘ λμ΄ κ° νλ‘μΈμ€μ νλ¦λλ‘ μ€ννλ€κ° νμν λλ§ μμ νλ‘μΈμ€λ₯Ό μκ±°νμ¬ λ©ν° νλ‘μΈμ±μ μ₯μ μ μ·¨νλλ‘ λ§λ€κ³ μΆμ κ²½μ°λ μμ κ²μ΄λ€. μ΄ λλ λ°λμ waitpidμ WNOHANGμ μ΄μ©ν΄μΌ νλ€.
Non-Blockμ μ΄μ©νλ μμλ₯Ό μλμμ λ€λ€λ³Ό κ²μΈλ°, λ€μκ³Ό κ°μ λ΄μ©μ΄λ€. λΆλͺ¨ νλ‘μΈμ€λ μμ νλ‘μΈμ€μ μν λ³νλ₯Ό SIGCHLDλΌλ μκ·Έλμ Kernelλ‘λΆν° λ°κ² λλ©΄, λ³λμ νΈλ€λ¬λ₯Ό νΈμΆνμ¬ μμ νλ‘μΈμ€μ statusλ₯Ό μ·¨λν λ€ μν©μ λ§λ μ μ ν νλμ μννλλ‘ νλ€. μ΄λ₯Ό ν΅ν΄ μνλ νμ΄λ°μ μ μ ν waitpidλ₯Ό νΈμΆν μ μμ λΏ μλλΌ, μμ νλ‘μΈμ€μ μ’
λ£λ₯Ό κΈ°λ€λ¦¬μ§ μκ³ λ μμ νλ‘μΈμ€μ μν λ³νμ λν΄μ statusλ₯Ό μ¦μ μ»μμΌλ‘μ¨ Non-Block μνλ‘ νλ¦μ μ΄μ΄κ° μ μκ² λλ€. λ§μΌ μ΄μ κ°μ μν©μμ WNOHANGμ μ¬μ©νμ§ μμΌλ©΄ μμ νλ‘μΈμ€κ° μ’
λ£λμ΄μΌλ§ statusλ₯Ό μ μ μκΈ° λλ¬Έμ, μμ νλ‘μΈμ€ μν λ³νλ₯Ό κ°μ§νκ³ μ΄μ λ°λΌ μ²λ¦¬ν΄μΌν νλμ λ°λ‘ λ°λ‘ μ²λ¦¬ν μ μκ² λλ€.
wait ν¨μλ₯Ό νΈμΆνκΈ° μ΄μ μλ μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€κ° κ°μ μμ μ Contextλ₯Ό μ΄μ΄κ°λ€λ μ μ μ΄μ©νμ¬ wait ν¨μλ₯Ό μ΅λν λ―Έλ€μ λΆλͺ¨ νλ‘μΈμ€ μ’
λ£ μ§μ λ±μμ νΈμΆνλλ‘ λ§λ€λ©΄ WNOHANGμ μ¬μ©ν κ²κ³Ό λμΌνκ² Non-Block μνλ‘ μ²λ¦¬λλλ‘ λ§λ€ μλ μμΌλ, μ΄ λμμ μ¬μ ν Non-Blockμ νμλ‘ νλ μν©μ λν΄μ μ μ°ν νλ¦μ λ§λ€μ΄λΌ μ μλ€.
4. μμ
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
pid_t ret;
int status;
pid = fork();
if (pid == -1)
return (1);
else if (!pid)
{
usleep(50000);
printf("Child1: I am the 1st Child\n");
return (2);
}
else
{
pid = fork();
if (pid == -1)
return (1);
else if (!pid)
{
usleep(49000);
printf("Child2: I am the 2nd Child\n");
return (3);
}
else
{
printf("Parent: I have 2 Children\n");
ret = wait(&status);
printf("Parent: Successfully got status from %d Child\n", ret);
printf("Parent: Exit Code is %d, Signal is %d\n", WEXITSTATUS(status), WTERMSIG(status));
ret = wait(&status);
printf("Parent: Successfully got status from %d Child\n", ret);
printf("Parent: Exit Code is %d, Signal is %d\n", WEXITSTATUS(status), WTERMSIG(status));
}
}
return (0);
}
C
볡μ¬
wait ν¨μλ 2κ° μ΄μμ forkλ νλ‘μΈμ€μ λν΄μ μμλ₯Ό 보μ₯νμ§ μλλ€λ κ²μ 보μ΄κΈ° μν΄ usleep ν¨μλ₯Ό μ μ ν μ΄μ©ν΄λ³΄μλ€. λ°λ³΅μ μΌλ‘ μ¬λ¬ μ°¨λ‘ μ€νν΄λ³΄λ©΄, μ΄λ¨ λλ 첫 λ²μ§Έ μμ νλ‘μΈμ€λ₯Ό λ¨Όμ μκ±°νκΈ°λ νκ³ , μ΄λ¨ λλ λ λ²μ§Έ μμ νλ‘μΈμ€λ₯Ό λ¨Όμ μκ±°νκΈ°λ νλ€. wait ν¨μλ forkμ μμμ κ΄κ³ μμ΄ λ¨Όμ λ§μΉ μμ νλ‘μΈμ€λ₯Ό μκ±°νκΈ° λλ¬Έμ μ¬λ¬ μμ νλ‘μΈμ€λ€μ λκ³ μ μμμ λ―Όκ°ν μμ
μ μνν΄μΌ νλ μν©μ΄λΌλ©΄, μ΄λ¬ν μμ
μ νλ‘κ·Έλ¨μ΄ μ€νλκ³ μλ λ¨Έμ μ μ±λ₯μ λ°λΌμλ μ°¨μ΄λ₯Ό λ³΄μΌ μ μκΈ° λλ¬Έμ μμ²λΌ wait ν¨μλ₯Ό μ΄μ©νλ κ²μ μ’μ λ°©λ²μ΄ μλλ€. wait ν¨μμ νκ³λ₯Ό 극볡νκΈ° μν΄μ μλ μ½λμ κ°μ΄ waitpid ν¨μμ μ§μ μ μΌλ‘ pidλ₯Ό λͺ
μν¨μΌλ‘μ¨ μμλ₯Ό 보μ₯νλλ‘ λ§λ€ μ μλ€.
μ¬μ© μ€μΈ λ¨Έμ μ λ°λΌμ μ μ½λλ₯Ό μ΄μ©νμ λ κ³ μ λ κ²°κ³Όκ° λμ¬ μ μλ€. usleep ꡬ문 μ΄νμ μ½λλ₯Ό μ²λ¦¬νλ μλκ° λ¨Έμ λ§λ€ λ€λ₯΄κΈ° λλ¬Έμ΄λ―λ‘, μ΄λ° κ²½μ°μλ usleepμ κ°μ μ μ ν μμ νλ©΄ λλ€.
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
pid_t pid1;
pid_t pid2;
pid_t ret;
int status;
pid1 = fork();
if (pid1 == -1)
return (1);
else if (!pid1)
{
usleep(50000);
printf("Child1: I am the 1st Child\n");
return (2);
}
else
{
pid2 = fork();
if (pid2 == -1)
return (1);
else if (!pid2)
{
usleep(49000);
printf("Child2: I am the 2nd Child\n");
return (3);
}
else
{
printf("Parent: I have 2 Children\n");
ret = waitpid(pid1, &status, 0);
printf("Parent: Successfully got status from %d Child\n", ret);
printf("Parent: Exit Code is %d, Signal is %d\n", WEXITSTATUS(status), WTERMSIG(status));
ret = waitpid(pid2, &status, 0);
printf("Parent: Successfully got status from %d Child\n", ret);
printf("Parent: Exit Code is %d, Signal is %d\n", WEXITSTATUS(status), WTERMSIG(status));
}
}
return (0);
}
C
볡μ¬
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
void handler(int sig)
{
pid_t ret;
int status;
if (sig != SIGCHLD)
exit(1);
ret = waitpid(-1, &status, WNOHANG);
printf("Parent: Successfully got status from %d Child\n", ret);
printf("Parent: Exit Code is %d, Signal is %d\n", WEXITSTATUS(status), WTERMSIG(status));
exit(0);
}
int main(void)
{
pid_t pid;
pid = fork();
if (pid == -1)
return (1);
else if (!pid)
{
printf("Child: I am going to take a sleep for 5 seconds\n");
usleep(5000000);
return (0);
}
else
{
printf("Parent: I have a Child which pid is %d\n", pid);
signal(SIGCHLD, handler);
while(1)
;
}
return (0);
}
C
볡μ¬
SIGCHLDλΌλ μκ·Έλμ μμ νλ‘μΈμ€μ μνμ λ³νκ° μμ λ Kenelλ‘λΆν° λΆλͺ¨ νλ‘μΈμ€μκ² μ λ¬λλ€. μΌλ°μ μΌλ‘ Kernelλ‘λΆν° SIGCHLDλ₯Ό λ°μ λΆλͺ¨ νλ‘μΈμ€μ κΈ°λ³Έ μ²λ¦¬ λμμ SIG_IGNμ΄λ€. μ΄μ λν΄μ κΈ°λ³Έ μ²λ¦¬ λμμ SIG_IGNμ΄ μλλΌ μ¬μ©μκ° μ μν νΈλ€λ¬λ‘ λμνλλ‘ signal ν¨μλ₯Ό μ΄μ©νμλ€. νΈλ€λ¬ λ΄λΆμλ waitpidλ₯Ό νΈμΆνμ¬ μμ νλ‘μΈμ€μ statusλ₯Ό μ»μ μ μλλ‘ νκ³ , WNOHANGμ μ΄μ©νμ¬ Block μνλ₯Ό λ°©μ§ν¨μΌλ‘μ¨ μ¦κ°μ μΈ λ°νμ μ λνλλ‘ νλ€. μμ κ°μ΄ μ²λ¦¬λ₯Ό νκ² λλ©΄, μμ νλ‘μΈμ€μ μν λ³νκ° λ°μνμ λ νΉμ νλμ μνν μ μλλ‘ λ§λ€ μ μλ€. λ§μΌ WNOHANGμ μ¬μ©νμ§ μμΌλ©΄ μμ νλ‘μΈμ€κ° μ’
λ£νκΈ° μ κΉμ§ Block μνμ λμ΄κ² λ λΏλ§ μλλΌ, μ·¨λν status μμ μμ νλ‘μΈμ€μ μν λ³νλ₯Ό λ΄κ³ μμ§ μκ³ μ’
λ£ μνμ λν΄μλ§ λ΄κ³ μλ μν©μ΄ λ²μ΄μ§λ€. λ°λΌμ μμ νλ‘μΈμ€μ μν λ³νμ λ°λ₯Έ νΉμ νλμ μννλλ‘ λ§λλλ° μ΄λ €μμ΄ μκΈ΄λ€. λ¬Όλ‘ μμ μμμ²λΌ Non-BlockμΌλ‘ νλ¦μ μ μ΄νλλΌλ μμ νλ‘μΈμ€κ° κ³ μ νλ‘μΈμ€λ‘ λ¨μ§ μλλ‘ μ£Όμν΄μΌ νλ€.
μκ·Έλμ λ°μμ λ κΈ°λ³Έ μ²λ¦¬ λμμ SIG_IGN, SIG_DFL, νΈλ€λ¬λ‘ λλλ©°, SIG_DFLμ κΈ°λ³Έ μ μλ νλμ νλΌλ κ²μΌλ‘ μ’
λ£, 무μ, λ€ν, μ€λ¨, μ¬κ° λ±μ΄ μλ€. μκ·Έλμ λν κΈ°λ³Έ μ²λ¦¬ λμμ signal, sigset, sigactionμ ν΅ν΄ μ¬μ μ ν μ μμΌλ©°, sigactionμ μ΄μ©νμ λλ νλμ μκ·Έλμ μ²λ¦¬νλ λμ λ€λ₯Έ μκ·Έλμ΄ μ€μ§ μλλ‘ νΉμ μκ·Έλλ€μ λ§μ μλ μλ€. μ΄λ₯Ό ν΅ν΄ μ‘°κΈ λ μ κ΅ν νλ‘κ·Έλ¨μ λ§λ€ μ μλ€
6) dup
1. μμ‘΄μ±
#include <unistd.h>
C
볡μ¬
2. ν¨μ μν
int dup(int fd);
C
볡μ¬
3. ν¨μ μ€λͺ
dup κ³μ΄μ ν¨μλ μ£Όλ‘ νμΌ λμ€ν¬λ¦½ν°λ₯Ό νμ©νλ ν¨μμ΄λ€. λ°λΌμ νμΌ λμ€ν¬λ¦½ν°μ λν μ΄ν΄κ° λ¨Όμ νμνλ€. μ΄μ λν΄μ get_next_lineμμ 리뷰ν λ°κ° μκΈ° λλ¬Έμ μ¬κΈ°μ μ€λ³΅μΌλ‘ λ€λ£¨μ§ μμ κ²μ΄λ€. dup νΉμ dup2μ λν μ€λͺ
μ μ½κΈ° μ μ λ°λμ μλ λ§ν¬μ νμΌ λμ€ν¬λ¦½ν°λ₯Ό νμΈνλ κ²μ κΆνλ€.
dup ν¨μλ fdλΌλ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μΈμλ‘ λ°λλ€. dup ν¨μμ λͺ©μ μ΄ νμΌ λμ€ν¬λ¦½ν°μ 볡μ μ΄λ―λ‘ λ°ν κ°μ 볡μ λ νμΌ λμ€ν¬λ¦½ν°μ κ°μ΄λλ€. λ§μΌ νμΌ λμ€ν¬λ¦½ν°λ₯Ό 볡μ νλ κ³Όμ μμ λ¬Έμ κ° λ°μνλ©΄, dup ν¨μλ -1μ΄λΌλ κ°μ λ°ννλ€.
get_next_lineμμ νμΌ λμ€ν¬λ¦½ν°μ λν λ΄μ©μ μ½μλ€λ©΄, νμΌμ μ΄λ©΄μ νμΌ λμ€ν¬λ¦½ν°κ° μ΄λ»κ² ν λΉνλμ§ μ΄ν΄νμ κ²μ΄λ€. dup ν¨μμ λ°ν κ°μ νμΌμ μ΄ λμ μν©κ³Ό λμΌν κΈ°λ²μ μ΄μ©νμ¬ μ»μ΄μ§λ€. λ°λΌμ dup ν¨μμ κ²½μ°μλ inodeμ λν μ 보λ₯Ό File Tableμ entryμ κΈ°λ‘νλ©΄μ μ΄μ λν μ£Όμλ₯Ό FD Tableμμ μ°Έμ‘°ν μ μλλ‘, μμ°¨μ μΌλ‘ FD Tableμ νμνλ κ³Όμ μ κ±°μΉλ€. FD Tableμ 곡κ°μ 0λ² indexλΆν° νμΈνμ¬ File Tableμ entry μ£Όμκ° λ΄κ²¨ μμ§ μμ indexλ₯Ό λ°ννλ―λ‘, μ¬μ©ν μ μλ νμΌ λμ€ν¬λ¦½ν° μ€μμ κ°μ₯ μμ κ°μ λ°ννκ² λλ€. μ΄ λ File Tableκ³Ό VFS inode Cacheλ μ΄λ»κ² λμνλμ§ μμ보μ.
μΌλ°μ μΌλ‘ λμΌν νμΌμ μ¬λ¬ μ°¨λ‘ μ¬λ νμλ νμΌμ΄ μ΄λ¦΄ λλ§λ€ λ³λμ File Tableμ entryλ‘ μ μ§λλ€κ³ νλ€. (μ΄ λ κ° File Tableμ entryκ° μ°Έμ‘°νλ inodeλ λμΌνλ©°, μ΄λ₯Ό μ°Έμ‘°νλ File Tableμ entry μμ λ°λΌ inodeμ i_count κ°μ΄ κ²°μ λλ€.) νμ§λ§ dup ν¨μμ κ²½μ° νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ»λλ€λ μ μ νμΌμ μ¬λ νμμ λμΌνμ§λ§, λ΄λΆμ μΌλ‘λ λ³λμ File Tableμ entryλ₯Ό λλ κ²μ΄ μλλΌ λμΌν File Tableμ entryλ₯Ό μ°Έμ‘°νλλ‘ λμ΄ μλ€. λ°λΌμ dup ν¨μλ₯Ό μννκ² λλ©΄ ν΄λΉ File Tableμ entryμμ f_count κ°μ΄ μ¦κ°νλ λ°©μμΌλ‘ λμνκ² λλ€.
dup ν¨μλ₯Ό μννκ² λλ©΄ μΈμλ‘ λ£μ νμΌ λμ€ν¬λ¦½ν°μ λ°ν κ°μΌλ‘ λ°μ νμΌ λμ€ν¬λ¦½ν°κ° λμΌν νμΌμ μ°Έμ‘°νκ³ μμ§λ§, close ν¨μλ κ°κ° νΈμΆν΄μ€μΌ νλ€λ μ μ μ μν΄μΌ νλ€. f_countμ κ°μ΄ 0μ΄ λμ΄μΌ File Tableμ entryκ° μμ λ μ μκ³ , μ΄μ λ°λΌ i_count κ°λ κ°μνμ¬ μ΅μ’
μ μΌλ‘λ μ¬λ°λ₯΄κ² VFS inode Cacheμμλ μμ λ μ μλ€. κ° νμΌ λμ€ν¬λ¦½ν°μ λν΄μ closeλ₯Ό νΈμΆν λλ§λ€ File Tableμ entryκ° κ°κ³ μλ f_count κ°μ΄ κ°μνκ² λλ€.
λ¬Όλ‘ close ν¨μλ₯Ό νΈμΆνμ§ μλλΌλ νλ‘μΈμ€κ° μ’
λ£λλ©΄ λͺ¨λ νμΌ λμ€ν¬λ¦½ν°λ μλμΌλ‘ λ«νκ² λλ€. λ°λΌμ νλ‘μΈμ€μ μ’
λ£ μμλ μλμΌλ‘ f_countκ° κ°μνλ€κ³ λ³Ό μ μλ€. μ΄μ λ°λΌ f_countκ° 0μ΄ λλ€λ©΄ μ±κ³΅μ μΌλ‘ File Tableμ entryλ ν΄μ λ κ²μ΄λ€. νλ‘μΈμ€μ μ’
λ£ μμ νμΌ λμ€ν¬λ¦½ν°κ° μλμΌλ‘ λ«νλ νμμ λν΄μλ exit ν¨μμ λμμΌλ‘ μ μλμ΄ μμΌλ©°, μ΄λ POSIXμ λ°λΌ νμ€μΌλ‘ μ μλ μ¬νμ΄λ€. νμ§λ§ μ¬μ©νμ§ μλ νμΌ λμ€ν¬λ¦½ν°μ λν μ μ ν close ν¨μμ νΈμΆμ΄ νλ‘κ·Έλ¨μ μμ±ν λ λ μ’μ μ΅κ΄μ λ§λ€κ³ , μκΈ°μΉ λͺ»ν λμμ λν΄μ λ°©μ§ν μ μλ€.
4. μμ
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
int fd;
int tmp;
int ret;
char buffer[4096];
tmp = open("test.txt", O_RDONLY);
fd = dup(tmp);
close(tmp);
if (fd == -1)
return (1);
ret = read(fd, buffer, 4096);
close(fd);
if (ret == -1)
return (1);
buffer[ret] = '\0';
write(STDOUT_FILENO, buffer, strlen(buffer));
return (0);
}
C
볡μ¬
7) dup2
1. μμ‘΄μ±
#include <unistd.h>
C
볡μ¬
2. ν¨μ μν
int dup2(int fd, int fd2);
C
볡μ¬
3. ν¨μ μ€λͺ
dup2μ μν μ dup ν¨μμ λμ λ°©μμ΄ λμΌνλ€. λ°λΌμ νμΌ λμ€ν¬λ¦½ν°μ λν λ΄μ©, νμΌ λμ€ν¬λ¦½ν°μ μ²λ¦¬ νλ¦, νμΌ λμ€ν¬λ¦½ν°μ 볡μ κ³Όμ μ λν΄μλ dup ν¨μλ₯Ό νμΈνλ κ²μ κΆνλ€.
dup2 ν¨μλ dup ν¨μμ λΉκ΅νμ λ, μ¬μ© λ°©λ²μ μ°¨μ΄κ° μλ€. μΈμλ‘ λ£μ fdλΌλ νμΌ λμ€ν¬λ¦½ν°λ₯Ό 볡μ νκ³ νμ¬ μ¬μ©νκ³ μμ§ μμ νμΌ λμ€ν¬λ¦½ν° μ€ κ°μ₯ μμ κ°μ λ°ννλ κ²μ΄ dupμ΄μλ€λ©΄, dup2μ κ²½μ°μλ λ°ν κ°μ΄ μ¬μ©μκ° μνλ fd2λΌλ κ°μ΄ λμ¬ μ μλλ‘ fdλΌλ μΈμλ₯Ό μ¬μ©νμ¬ λ³΅μ λ₯Ό μννλ€. μ¦, 볡μ κ³Όμ μμ λ¬Έμ κ° μκΈ°μ§ μλλ€λ©΄ dup2μ λ°ν κ°μ fd2κ° λλ€.
볡μ κ³Όμ μμ λ¬Έμ κ° μκΈ΄λ€λ©΄ dup ν¨μμ λ§μ°¬κ°μ§λ‘, dup2 ν¨μλ -1μ λ°ννλ€.
λ§μΌ 볡μ κ³Όμ μμ fd2κ° κΈ°μ‘΄μ μ΄λ―Έ μ΄λ €μ μ¬μ©λκ³ μλ κ°μ΄λΌλ©΄ μ΄λ»κ² λ κΉ? μ΄λ 볡μ κ³Όμ μμμ μ€λ₯λ‘ μ²λ¦¬νμ§ μκ³ κΈ°μ‘΄μ νμΌ λμ€ν¬λ¦½ν°λ₯Ό closeνμ¬ File Tableμ entryμ inodeλ₯Ό μ²λ¦¬νμ¬, File Tableμ entryλ₯Ό μ°Έμ‘°νκ³ μμ§ μμ μνμ νμΌ λμ€ν¬λ¦½ν°λ‘ λ§λ€μ΄μ 볡μ λ₯Ό μνν μ μλλ‘ λ§λ λ€.
dup ν¨μκ° μ΄λ―Έ μ‘΄μ¬νλλ°λ λΆκ΅¬νκ³ dup2 ν¨μλ₯Ό λ§λ€μ΄λ μ΄μ λ μ μ°ν νμΌ λμ€ν¬λ¦½ν°μ μ΄μ©μ μν΄μμ΄λ€. dup2 ν¨μλ μ£Όλ‘ pipe ν¨μμ ν¨κ» λ§μ΄ μ°μ΄λλ°, pipe ν¨μμμ μ¬μ©λλ νμΌ λμ€ν¬λ¦½ν°λ₯Ό νμ€ μ
λ ₯κ³Ό νμ€ μΆλ ₯μ μ°Έμ‘°νλ indexκ° λ³΅μ ν μ μλλ‘ μ£Όλ‘ μ¬μ©λλ€. μ΄λ₯Ό ν΅ν΄ pipeλ‘ μ°κ²°λ νλ‘μΈμ€ κ°μ λͺ
λ Ήμ΄λ₯Ό μ²λ¦¬ν λ νμ€ μ
λ ₯κ³Ό νμ€ μΆλ ₯μ μ΄μ©νκΈ° μν΄ 0λ² indexμ 1λ² indexλ₯Ό μ΄μ©νλ€λ©΄, μ€μ λ‘λ νμ€ μ
λ ₯κ³Ό νμ€ μΆλ ₯μ μ΄μ©νλ κ²μ΄ μλλΌ λ³΅μ ν νμΌ λμ€ν¬λ¦½ν°μ νμΌμ μ΄μ©νκ² λλ€. pipeμ λν΄μ μ°¨νμ νλͺ©μμ λ€λ£¨λ―λ‘ μ΄μ λΉμ·ν μμλ₯Ό μλμμ λ€λ€λ³Ό κ²μ΄λ€.
λ§μΌ dup2κ° μ‘΄μ¬νμ§ μμμ dupμΌλ‘λ§ μ΄λ₯Ό μ²λ¦¬ν΄μΌ νλ€λ©΄ κ΅μ₯ν κΉλ€λ‘μ΄ μν©μ΄ λ°μν μ μλ€. μ¬μ©μκ° μνλ κ° μ΄μ κΉμ§λ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ΄μ΄λ¬μΌ νκ³ , μ¬μ©μκ° μνλ κ°μ΄ μ΄λ―Έ μ μ λμλ€λ©΄ closeλ₯Ό νΈμΆν΄μ€μΌ νλ€. λ§μΉ¨λ΄ dupμ νΈμΆνκ² λμ΄ μνλ κ°μ ν λΉ λ°μλ€λ©΄, μ΄λ₯Ό μν΄ μ΄μ μ μ΄μ΄λ μ¬μ©λμ§ μλ νμΌ λμ€ν¬λ¦½ν°λ₯Ό close νλ κ³Όμ μ κ±°μ³μΌ νλ€. λ¬Όλ‘ μ΄μ κ°μ 볡μ‘ν κ³Όμ μ΄ μ«μ΄μ dup2μ λμΌν λμμ λ§λ€μ΄ λ΄μ§ μλλ€κ³ νλ€λ©΄, λ¨μν dup ν¨μλ§μ μ΄μ©νκ³ λ°ν λ°μ νμΌ λμ€ν¬λ¦½ν°λ₯Ό λ¬Έμ μμ΄ μ¬μ©ν μ μλλ‘ dup ν¨μμ νΈμΆμμμ μ΄λ₯Ό μ μ ν μ²λ¦¬ν΄μ€μΌ νλ μν©μ΄ λ°μνλ€.
μμμμ μ¬μ©λ μ½λμ μν©μ μμ κ·Έλ¦Όκ³Ό κ°μ μν©μ΄λ€. μ΄ λ dup2λ₯Ό νΈμΆνκ² λλ©΄ κΈ°μ‘΄ 0λ² indexμ νμΌ λμ€ν¬λ¦½ν°κ° λ«νκ³ , 3λ² indexμ λν File Tableμ entryλ₯Ό μ°Έμ‘°νλλ‘ λ³΅μ κ° μ΄λ€μ§λ€. 볡μ νμ κΈ°μ‘΄ 0λ² indexκ° μ°Έμ‘°νκ³ μλ File Tableμ entryκ° νμ¬ νλ‘μΈμ€μ μν΄μ μ ν μ°Έμ‘°λκ³ μμ§ μμμλ File Tableμμ ν΄μ λμ§ μμ μ΄μ λ λ€λ₯Έ νλ‘μΈμ€λ€λ νμ€ μ
λ ₯μ μν΄μ ν΄λΉ entryλ₯Ό μ°Έμ‘°νκ³ μκΈ° λλ¬Έμ΄λ€. (μ¦, νμ€ μ
λ ₯μ μν entryμ f_countλ λΉλ‘ νμ¬ νλ‘μΈμ€μ 0λ² indexκ° μ°Έμ‘°λ₯Ό λλλΌλ 0μ΄ λλ κ²½μ°λ μλ€κ³ 보면 λλ€.)
4. μμ
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd;
int tmp;
int ret;
char buffer[4096];
tmp = open("test.txt", O_RDONLY);
fd = dup2(tmp, STDIN_FILENO);
close(tmp);
if (fd == -1)
return (1);
ret = read(STDIN_FILENO, buffer, 4096);
if (ret == -1)
return (1);
buffer[ret] = '\0';
write(STDOUT_FILENO, buffer, strlen(buffer));
return (0);
}
C
볡μ¬
8) pipe
1. μμ‘΄μ±
#include <unistd.h>
C
볡μ¬
2. ν¨μ μν
int pipe(int fd[2]);
C
볡μ¬
3. ν¨μ μ€λͺ
νν νλ‘μΈμ€ κ°μ ν΅μ μ IPC (Inter Process Communication)μ΄λΌ λΆλ₯Έλ€. IPCλ₯Ό μννκΈ° μν΄μ λ°μ΄ν°λ₯Ό μ£Όκ³ λ°κΈ° μν νΉμ 곡κ°μ΄ μꡬλλ€. νμ§λ§ νλ‘μΈμ€λ€μ λ©λͺ¨λ¦¬ μμ κ°κ° λ
립λ 곡κ°μ ν λΉλ°μ μμΉνκ³ , μ΄λ€μ μλ‘ κ³΅μ λ μ μκΈ° λλ¬Έμ νΉλ³ν λ°©μ μμ΄λ IPC μνμ μ΄λ €μμ΄ μλ€.
IPCλ₯Ό μννκΈ° μν λ°©μμΌλ‘λ νμΌ, λ©μΈμ§ ν, 곡μ λ©λͺ¨λ¦¬ μμΌ λ±μ΄ μμΌλ©°, fork, wait, waitpidμμ μκ°λ μκ·Έλλ IPC λ°©μ μ€ νλμ΄λ€. μ΄μ κ°μ IPC λ°©μμ ν¬κ² 곡μ λ©λͺ¨λ¦¬ κΈ°λ²κ³Ό λ©μΈμ§ κ΅ν κΈ°λ²μΌλ‘ λλλλ°, λ©μΈμ§ κ΅ν κΈ°λ² μ€μμλ forkλ₯Ό μ΄μ©νμ λ μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€κ° μλ‘ ν΅μ νλλ° μ΄μ©λλ IPC λ°©μμ΄ νμ΄νμ΄λ€.
μ μλ IPC λ°©μλ€μ΄ λͺ¨λ μλ°©ν₯ ν΅μ μ μ§μνλ κ²μ μλλ€. λ°λΌμ μ¬μ©νλ €λ IPC λ°©μμ΄ μλ°©ν₯ ν΅μ μ μ§μνλμ§ λ¨Όμ νμΈνκ³ , κ·Έλ μ§ μλ€λ©΄ μλ°©ν₯ ν΅μ μ μν΄ λ³λμ μμ
μ κ±°μ³μΌ νλ€.
μ΄μ νλͺ©μ μμμμ μμ±λ μ½λλ₯Ό 보면 μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€ κ°μ μκ·Έλμ μ£Όκ³ λ°λ κ²μ λ³Ό μ μλλ°, μ΄λ 보λ΄μ§ μκ·Έλμ λ°λΌ κ° νλ‘μΈμ€κ° μνν λμμ μ μνλ λ±μΌλ‘ μ¬μ©λκΈ° λλ¬Έμ μνΈ κ°μ λ°μ΄ν°λ₯Ό μ£Όκ³ λ°λλ°λ μ΄λ €μμ΄ μλ€. λ°λΌμ μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€κ° μλ‘ λ°μ΄ν°λ₯Ό μ£Όκ³ λ°κΈ° μν΄μ μκ·Έλ보λ€λ νμ΄νλ₯Ό μ΄μ©ν΄μΌ νλ€. μ΄ λ, μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€ μ¬μ΄μ νμ΄νλ₯Ό λκΈ° μν΄ μ΄μ©λλ ν¨μκ° pipeμ΄λ€.
νμ΄νλΌλ IPC λ°©μμ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ΄μ©νμ¬ μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€ κ°μ λ°μ΄ν°λ₯Ό μ£Όκ³ λ°μ μ μλλ‘ ν΄μ€λ€. νμ΄νλ λ¨λ°©ν₯ ν΅μ μ΄κΈ° λλ¬Έμ, μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€ κ° νμ΄νλ₯Ό κ°μ€νκ² λλ©΄ ν μͺ½μμλ Read μμ
λ§ κ°λ₯νκ³ λ€λ₯Έ μͺ½μμλ Write μμ
λ§ κ°λ₯νλ€. κ·Έλ¦¬κ³ λΉλ‘ νμ΄νκ° νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ΄μ©νκΈ΄ νλ, μ΄λ νμΌμ λν νμΌ λμ€ν¬λ¦½ν°κ° μλ μ΄μ체μ λ‘λΆν° ν λΉ λ°μ νΉμ λ²νΌμ λν νμΌ λμ€ν¬λ¦½ν°μ΄λ€. λ°λΌμ νμ΄νμ Writeν μ μλ λ°μ΄ν°λ ν λΉ λ°μ λ²νΌμ ν¬κΈ°λ§νΌμ΄λΌλ μ νμ΄ μλ€.
λ°λΌμ μ΄μ μ μΈκΈνλ κ²μ²λΌ νμ΄νλ₯Ό μ΄μ©νμ¬ λ νλ‘μΈμ€κ° μλ°©ν₯ ν΅μ μ μν΄μ , κ° νλ‘μΈμ€κ° λͺ¨λ μ½κ³ μ°λ μμ
μ΄ κ°λ₯ν΄μΌ νλ―λ‘ 2κ°μ νμ΄νλ₯Ό λμ΄μΌ νλ€.
νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ΄μ©νμ¬ νλ‘μΈμ€ κ°μ ν΅μ μ΄ κ°λ₯ν μ΄μ λ νμΌ λμ€ν¬λ¦½ν°κ° μ°Έμ‘°νλ νμΌ μ체λ λμ€ν¬ μμ λ³λμ 곡κ°μΌλ‘ μ μ§λλ©΄μ νλ‘μΈμ€μ λ©λͺ¨λ¦¬ 곡κ°μ μΉ¨ν΄νμ§ μκ³ , μ΄λ€μ μ΄λ€ νλ‘μΈμ€μμλ μ κ·Όμ΄ κ°λ₯νκΈ° λλ¬Έμ΄λ€. μ¦, μ΄λ‘ μ μΌλ‘ κ° νλ‘μΈμ€μμ μ¬μ©νκ³ μλ Read μ©λμ νμΌ λμ€ν¬λ¦½ν°μ Write μ©λμ νμΌ λμ€ν¬λ¦½ν°κ° λμΌν νμΌμ μ°Έμ‘°νλλ‘ λμ΄ μλ€λ©΄, ν΄λΉ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ½κ³ μ°λ©΄μ ν΅μ μ΄ κ°λ₯νκ² λλ κ²μ΄λ€.
μ΄μ κ°μ μμ
μ΄ νΉν μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€ κ°μ λ§μ΄ μ΄μ©λλ μ΄μ λ μμ νλ‘μΈμ€μ μμ±μ΄ forkλ₯Ό ν΅ν΄μ μ΄λ€μ§κ³ , fork ν¨μλ λΆλͺ¨ νλ‘μΈμ€μ λͺ¨λ λ©λͺ¨λ¦¬ 곡κ°κ³Ό PCκΉμ§ κ·Έλλ‘ λ³΅μ νμ¬ μμ νλ‘μΈμ€μκ² ν λΉνλ νΉμ±μ κ°κ³ μκΈ° λλ¬Έμ΄λ€. λ°λΌμ fork μν μ΄μ μ pipe ν¨μλ₯Ό νΈμΆνμ¬ Read, Write μ©λμ λ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ°κ²°ν΄λμλ€λ©΄, fork ν¨μ μν μ΄νμ μμ νλ‘μΈμ€μμλ μ΄ μνκ° κ·Έλλ‘ μ μ§λκ³ μκ² λλ€. λΉλ‘ νμΌ λμ€ν¬λ¦½ν°κ° νλ‘μΈμ€ λ¨μλ‘ κ΄λ¦¬λκΈ°λ νμ§λ§ μ΄λ―Έ μλ‘ λμΌν νμΌμ μ°Έμ‘°νλλ‘ μ€μ λμ΄ μκΈ° λλ¬Έμ μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€λ μννκ² ν΅μ ν μ μλ€.
ν¨μμ ννλ₯Ό μ΄ν΄λ³΄λ©΄, pipe ν¨μλ μμμ μ€λͺ
λ κ²μ²λΌ 2κ°μ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μΈμλ‘ λ°μ μ΄μ©νλ κ²μ λ³Ό μ μλ€. pipeμ fdμ νμΌ λμ€ν¬λ¦½ν°λ€μ΄ μ±κ³΅μ μΌλ‘ ν λΉλλ€λ©΄ μ΄ κ°μ μ΄μ©ν μ μκ² λκ³ 0μ λ°νννλ€. fdμ νμΌ λμ€ν¬λ¦½ν°λ₯Ό ν λΉνλ κ³Όμ μμ λ¬Έμ κ° μκΈ΄λ€λ©΄ pipeλ μ¦μ -1μ λ°ννλ€.
μ΄ λ μΈμλ‘ μ¬μ©λλ fdλ ν¬κΈ°κ° 2μΈ int νμ
μ λ°°μ΄μΈλ°, fd[0]μ Readμ μ΄μ©λκ³ fd[1]μ Writeμ μ΄μ©λλ€. μμ κ·Έλ¦Όμ²λΌ aλΌλ νλ‘μΈμ€μμ fd[1]μ μ΄μ©νμ¬ hiλ₯Ό μΌλ€λ©΄, bλΌλ νλ‘μΈμ€μμλ fd[0]μ μ΄μ©νμ¬ hiλ₯Ό μ½μ μ μλ€λ κ²μ΄λ€.
μλ μμμμ pipeμμ μ¬μ©ν νμΌ λμ€ν¬λ¦½ν°λ₯Ό ν λΉ λ°κ³ , μ΄λ₯Ό κ°κ° dup2λ₯Ό μ΄μ©νμ¬ νμ€ μ
λ ₯μ μν indexμ νμ€ μΆλ ₯μ μν indexλ‘ λ³΅μ ν¨μΌλ‘μ¨ μ£Όκ³ λ°μ λ°μ΄ν°λ₯Ό νμΌμ κΈ°λ‘ν΄λ³Ό κ²μ΄λ€. μμμ λν κ° νλ‘μΈμ€μ μν©μ μλ κ·Έλ¦Όκ³Ό κ°λ€.
μμ νλ‘μΈμ€
λΆλͺ¨ νλ‘μΈμ€
4. μμ
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#define P_READ 0
#define P_WRITE 1
#define BUFFER_SIZE 4096
void childcommand(void)
{
int ret;
char buffer[BUFFER_SIZE];
ret = read(STDIN_FILENO, buffer, BUFFER_SIZE);
buffer[ret] = '\0';
write(STDOUT_FILENO, buffer, strlen(buffer));
}
void childproc(int pipe[2])
{
int fd;
int r_fd;
int w_fd;
printf("Child: I'm going to close fd for Read\n");
printf("Child: I'm going to connect STDOUT to fd for Write\n");
printf("Child: I'm going to connect STDIN to fd from a file\n");
printf("Child: Eventually I'll read from STDIN (file) and write to STDOUT (pipe)\n");
close(pipe[P_READ]);
w_fd = dup2(pipe[P_WRITE], STDOUT_FILENO);
close(pipe[P_WRITE]);
if (w_fd == -1)
exit(1);
fd = open("read.txt", O_RDONLY);
if (fd == -1)
exit(1);
r_fd = dup2(fd, STDIN_FILENO);
close(fd);
if (r_fd == -1)
exit(1);
childcommand();
}
void parentcommand(void)
{
int ret;
char buffer[BUFFER_SIZE];
ret = read(STDIN_FILENO, buffer, BUFFER_SIZE);
buffer[ret] = '\0';
write(STDOUT_FILENO, buffer, strlen(buffer));
}
void parentproc(int pipe[2], pid_t pid)
{
int fd;
int r_fd;
int w_fd;
printf("Parent: I'm going to close fd for Write\n");
printf("Parent: I'm going to connect STDIN to fd for Read\n");
printf("Parent: I'm going to connect STDOUT to fd from a file\n");
printf("Parent: Eventually I'll read from STDIN (pipe) and write to STDOUT (file)\n");
close(pipe[P_WRITE]);
r_fd = dup2(pipe[P_READ], STDIN_FILENO);
close(pipe[P_READ]);
if (r_fd == -1)
exit(1);
fd = open("write.txt", O_WRONLY);
if (fd == -1)
exit(1);
w_fd = dup2(fd, STDOUT_FILENO);
close(fd);
if (w_fd == -1)
exit(1);
if (waitpid(pid, NULL, 0) == -1)
exit(1);
parentcommand();
}
int main(void)
{
int fd[2];
pid_t pid;
if (pipe(fd) == -1)
return (1);
printf("Parent: fd for Read is %d, fd for Write is %d\n", fd[P_READ], fd[P_WRITE]);
pid = fork();
if (pid == -1)
{
close(fd[P_READ]);
close(fd[P_WRITE]);
return (1);
}
else if (!pid)
childproc(fd);
else
parentproc(fd, pid);
return (0);
}
C
볡μ¬
9) execve
1. μμ‘΄μ±
#include <unistd.h>
C
볡μ¬
2. ν¨μ μν
int execve(const char *file, char * const *argv, char * const *envp);
C
볡μ¬
3. ν¨μ μ€λͺ
μ κ·Έλ¦Όμ 보면 μ μ μλ―μ΄ exec κ³μ΄μ ν¨μλ λ€μνμ§λ§, 첫 λ²μ§Έ μΈμλ‘ μ€νν νμΌμ κ²½λ‘λ₯Ό λ°λλ€λ κ²μλ μ°¨μ΄κ° μλ€. exec κ³μ΄μ ν¨μλ₯Ό μ΄μ©νλ©΄ 첫 λ²μ§Έ μΈμλ₯Ό μ΄μ©νμ¬ ν΄λΉ κ²½λ‘μ νμΌμ μ€ννλ©΄μ μλ‘μ΄ νλ‘μΈμ€λ₯Ό λ§λ€μ΄λ΄κ³ , νμ¬ νλ‘μΈμ€μμ μλ‘κ² λ§λ€μ΄μ§ νλ‘μΈμ€λ‘ νλ¦μ κ΅μ²΄νλ€. μ΄ λ μλ‘μ΄ νλ‘μΈμ€ λ΄μλ μλ‘κ² μ΄κΈ°ν λ μ€ν, ν, λ°μ΄ν° μμμ κ°λλ€. μ΄λ forkμ κ°μ΄ λ³λμ νλ‘μΈμ€κ° ꡬλλλ κ²μ΄ μλ, μλ‘μ΄ νλ‘μΈμ€κ° νμ¬ νλ‘μΈμ€λ₯Ό κ΅μ²΄νλ νμλ‘ μ΄λ€μ§κΈ° λλ¬Έμ μμ νλ‘μΈμ€μ λΆλͺ¨ νλ‘μΈμ€μ κ΄κ³λ₯Ό κ°λ ννκ° μλλ€. λ°λΌμ exec κ³μ΄μ ν¨μλ‘ μμ±λ νλ‘μΈμ€λ λκΈ°μ μΈ νΉμ±μ κ°λλ€.
μλ₯Ό λ€μ΄ νμ¬ νλ‘μΈμ€ λ΄μμ exec κ³μ΄ ν¨μκ° μ²« λ²μ§Έ μΈμλ‘ /bin/lsλ₯Ό μ΄μ©νλ€λ©΄ exec ν¨μμ μν΄μ /bin/lsκ° μ€νλλ©΄μ μλ‘μ΄ νλ‘μΈμ€κ° μκΈ°κ³ , μ€ν νλ¦μ /bin/lsλ‘ λμ΄κ°κ² λλ€. μ¬κΈ°μ μλ‘μ΄ νλ‘μΈμ€λ₯Ό μμ±λλ κ²μ΄ μΈμλ₯Ό μ€νμν€λ©΄μ μ΄λ€μ§λ κ²μ΄λ―λ‘, exec κ³μ΄μ 첫 λ²μ§Έ μΈμμ λν΄μ μ€ν κΆνμ΄ μλμ§ νμΈμ΄ κΌ νμνλ€. μ΄λ μμμ λ°°μ΄ access ν¨μλ₯Ό ν΅ν΄μ μ ν κ²μ¬κ° κ°λ₯νλ€.
λ§μΌ exec κ³μ΄μ ν¨μκ° μΈμλ‘ λ°μ νμΌμ λν΄μ μ€ννκ³ μ΄λ₯Ό μ²λ¦¬νλλ° μλ¬΄λ° λ¬Έμ κ° μλ€λ©΄, 0μ λ°ννλ€. λ°λλ‘ λ¬Έμ κ° μκΈ°κ² λλ©΄, -1μ λ°ννλ€. μ΄λ₯Ό μ λ
ν΄λκ³ κ° ν¨μλ€μ λν΄μ μμ보μ.
exec κ³μ΄μ ν¨μλ κ·Έ μ΄λ¦λ€μμ μ΄λ€ κ·μΉμ μ°Ύμ μ μλλ°, ν¨μ μ΄λ¦ λ€μ l, v, e, pκ° λΆλ κ²μ λ³Ό μ μλ€. lμ list, vλ vector, eλ environment, pλ pathλ₯Ό μλ―Ένλ€.
μ μ¬ν μ΄ν΄λ³΄λ©΄ λ체μ μΌλ‘ execl κ³μ΄κ³Ό execv κ³μ΄λ‘ λλλ κ²μλ³Ό μ μλλ°, lκ³Ό vκ° κ³§ exec ν¨μλ‘ μ€νν νμΌμ μ¬μ©λλ κ°μ listλ‘ μΌμΌμ΄ μ£Όμ΄μ€μ§ vectorλ‘ ν λ²μ μ£Όμ΄μ€μ§λ₯Ό μλ―Ένλ―λ‘, λ λ²μ§Έ μΈμ μ΄ν λΆν° μΈμμ ννκ° λ¬λΌμ§λ κ²μ λ³Ό μ μλ€. l κ³μ΄ ν¨μλ€μ κ°λ³ μΈμλ₯Ό μ΄μ©νλ κ²μ λ³Ό μ μκ³ , v κ³μ΄ ν¨μμμλ κ°λ³ μΈμλ₯Ό μ΄μ©νμ§ μλ κ²μ λ³Ό μ μλ€.
μ΄ λ l κ³μ΄μ΄λ v κ³μ΄μ΄λ λ λ²μ§Έ μΈμλ₯Ό μ΄μ©ν λ μ£Όμν μ μ΄ μλλ°, νμΌμ μ€ννλ©΄μ μκΈ°λ μλ‘μ΄ νλ‘μΈμ€μλ argcμ λν μ λ³΄κ° μκΈ° λλ¬Έμ argvμ κ°μ₯ λ§μ§λ§ μμμλ NULLμ΄ μμ΄μΌ νλ€. κ·Έλ¦¬κ³ argvκ° μΈμλΌκ³ νλλΌλ argvμ κ°μ₯ 첫 μμμλ μ¬μ©ν λͺ
λ Ήμ΄κ° λ°λμ κΈ°μ¬ λμ΄μΌ νλ€. execlκ³Ό execvλ₯Ό μ΄μ©νμ¬ ls -al test.txtλ₯Ό μ΄μ©νκ³ μν λ μ΄λ€ μμΌλ‘ κ° ν¨μμ μΈμλ₯Ό λμ΄μΌ νλμ§ μκ°ν΄λ³΄μ.
execl (calling ls -al test.txt)
execv (calling ls -al test.txt)
l κ³μ΄ ν¨μλ₯Ό μ΄μ©ν μ§ v κ³μ΄ ν¨μλ‘ μ΄μ©ν μ§ μ ν λ€μλ μ€νν νμΌμ μλ κ²½λ‘λ‘ μ€μ§, μ λ κ²½λ‘λ‘ μ€ μ§μ λ°λΌ pμ μ λ¬΄κ° κ°λ¦°λ€. pλ₯Ό μ΄μ©ν execlp, execvpμ κ°μ ν¨μλ€μ $PATHλΌλ νκ²½ λ³μλ₯Ό μ΄μ©νμ¬ μ²« λ²μ§Έ μΈμλ₯Ό μ²λ¦¬νλ€. μ΄μ κ°μ ν¨μλ€μ $PATHμ λ±λ‘λ κ²½λ‘ λ΄μ λμΌν νμΌμ΄ μλ κ²½μ°μ λ¬Έμ κ° λλ€. νΉν μ΄μ κ°μ λ¬Έμ λ $PATH λ΄μ κ²½λ‘λ₯Ό μ½μ
νμ¬ μ€νν νλ‘κ·Έλ¨μ λν΄ κ°μ λ‘ λ°κΎΈλ κ²μ΄ κ°λ₯νκΈ° λλ¬Έμ 보μ μ·¨μ½ λ¬Έμ λ‘ μ΄μ΄μ§ μ μλ€. λ°λΌμ μ λ κ²½λ‘λ₯Ό μ΄μ©νλ λλ¨Έμ§ ν¨μλ€μ μ΄μ©νλ κ²μ΄ μ’λ€.
execμ e κ³μ΄ ν¨μλ€μΈ execle, execveμ κ°μ ν¨μλ€μ eμ μλ―Έμμ μ μ μλ―μ΄, νκ²½ λ³μλ₯Ό ν¨μμ κ°μ₯ λ§μ§λ§ μΈμλ‘ λ겨μ λ΄λΆμ μΌλ‘ μ΄λ₯Ό μ΄μ©νλ€. νκ²½ λ³μλ₯Ό μ¬μ©νμ§ μμ κ²μ΄λΌλ©΄ execl νΉμ execvλ₯Ό μ¨λ μ’μ§λ§, execle νΉμ execveλ₯Ό μ¬μ©νλ©΄μ νκ²½ λ³μμ ν΄λΉνλ μΈμμ NULLμ μ£Όμ΄λ λλ€. e κ³μ΄ ν¨μλ€μ μ΄μ©νλ©΄μ μ£Όμν μ μ κ°μ₯ λ§μ§λ§ μΈμλ‘ νκ²½ λ³μλ₯Ό λκΈΈ λ, μΈμμ κ°μ₯ λ§μ§λ§ μμλ NULLμ΄μ΄μΌ νλ€λ κ²μ΄λ€.
execle ν¨μκ° μ€νν νμΌμ λκΈΈ μΈμλ€μ κ°λ³ μΈμλ‘ μ²λ¦¬ νμμλ κ°μ₯ λ§μ§λ§ μΈμλ₯Ό νκ²½ λ³μλ‘ μΈμν μ μλ μ΄μ λ κ°μ₯ λ§μ§λ§ μΈμ μ΄μ μ NULLλ‘ κ΅¬λΆμ΄ λμ΄ μκΈ° λλ¬Έμ΄λ€.
execve ν¨μλ₯Ό ν΅ν΄ gccλ₯Ό μ€νν¨μΌλ‘μ¨, μλ‘μ΄ μ€ν νμΌμ λ§λ€μ΄ 보λ κ³Όμ μ μμ보μ.
4. μμ
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int i;
char **args;
if (argc == 1)
return (1);
i = -1;
args = (char **)malloc(argc * sizeof(char *));
if (!args)
return (1);
args[argc - 1] = NULL;
while (++i < argc - 1)
args[i] = argv[i + 1];
execve("/usr/bin/gcc", args, NULL);
free(args);
return (0);
}
C
볡μ¬
2. Approach
1) λ€μ€ λͺ λ Ήμ΄
λͺ
λ Ήμ΄ μλ³΄λ€ νλ μμ λ§νΌ νμ΄νκ° μ‘΄μ¬νλ―λ‘ κΈ°μ‘΄μλ μλ μμ¬ μ½λμ κ°μ΄ νμ΄νμ μλ§νΌ λμ ν λΉμ λ°κ³ , λ°λ³΅λ¬Έμ λ λ indexλ₯Ό κ³μ°νμ¬ pipe ν¨μμ λ£λλ‘ λ§λ€μλ€.
int i;
int *fd;
fd = (int *)malloc(num_pipe * 2 * sizeof(int));
if (!fd)
exit (1);
i = -1;
while (++i < num_pipe)
if (pipe(num_pipe * 2) < 0)
exit(1);
/*
** cmd0 cmd1 cmd2 cmd3 cmd4 ...
** pipe0 pipe1 pipe2 pipe3 ...
** [0,1] [2,3] [4,5] [6,7] ...
*/
C
볡μ¬
μ°μ μμ κ°μ λ°©λ²μ λν΄μ νμ΄νλ‘ μ¬μ©ν νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ»λλ° λμ ν λΉμ μ¬μ©νλ€λ μ μ΄ λ§μμ λ€μ§ μμκ³ , μ²λ¦¬ν΄μΌν λͺ
λ Ήμ΄λ€μ΄ λ§μ νμ΄νλ₯Ό μꡬνλ€λ©΄ κ·Έμ λΉλ‘νλ λ©λͺ¨λ¦¬λ₯Ό μ΄μ©ν΄μΌ νλ€λ μ λ λ§μμ λ€μ§ μμλ€.
λ°λΌμ νμ΄νλ₯Ό μ κ² μΈ μ μλ λ°©λ²μ λν΄μ κ³ λ―Όμ νλ€κ°, νμ΄νκ° λ¨λ°©ν₯ ν΅μ μΌλ‘ μ΄μ©λλ€λ μ κ³Ό forkλ‘ μμ±λ λΆλͺ¨ λ° μμ κ΄κ³μ νλ‘μΈμ€λ μλ‘ λμΌν λ©λͺ¨λ¦¬ ꡬ쑰λ₯Ό κ°λ μ μ μ΄μ©νμ¬ 2κ°μ νμ΄νλ§μΌλ‘ λ€μ€ λͺ
λ Ήμ΄λ₯Ό μ²λ¦¬ν μ μλλ‘ κ΅¬μν΄λ³΄μλ€.
μ΄μ λ°©λ²μμ μ£Όμ΄μ§ νμ΄νκ° μ΄μ©νλ Readμ Writeμ νμΌ λμ€ν¬λ¦½ν°λ₯Ό 2κ°λ‘ μ€μμ λ λμμ μλμ μμ¬ μ½λλ‘ λνλΈ κ²μ²λΌ λͺ
λ Ήμ΄μ indexκ° μ§μμΌ λλ B νμ΄νμμ μ½κ³ A νμ΄νμ μ°λ©°, νμμΌ λλ A νμ΄νμμ μ½κ³ B νμ΄νμ μ°λ κ²μ μ μ μλ€.
/*
** cmd0 -> Read from file, Write on A pipe
** cmd1 -> Read from A pipe, Write on B pipe
** cmd2 -> Read from B pipe, Write on A pipe
** cmd3 -> Read from A pipe, Write on B pipe
** ...
*/
C
볡μ¬
λ°λΌμ λͺ
λ Ήμ΄λ§νΌμ λ°λ³΅λ¬Έμ λλ¦¬κ³ λ΄λΆμμ forkλ₯Ό ν΅ν΄ λͺ
λ Ήμ΄λ₯Ό μνν μμ νλ‘μΈμ€λ₯Ό λ§λ λ€κ³ νμ λ, μμ νλ‘μΈμ€μ λ°λ³΅λ¬Έ indexκ° μ§μμΈμ§ νμμΈμ§μ λ°λΌ μ΄λ€ νμ΄νμ Read νΉμ Writeλ₯Ό μ΄μ©ν μ§ λ§λ€μ΄μ£Όλ©΄ λλ€. λ§μΌ μ¬μ©νμ§ μλ Writeμ λν νμΌ λμ€ν¬λ¦½ν°κ° μμ νλ‘μΈμ€μμ λ¨μ μκ² λλ©΄ λͺ
λ Ήμ΄ μ²λ¦¬ μ 무νν λκΈ°νλ νμμ λ³Ό μ μκΈ° λλ¬Έμ Writeμ λν νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ μ ν λ«λ κ³Όμ μ΄ νμνλ€. μ΄λ λ¨μν μμ νλ‘μΈμ€μμ ν΄λΉ νμΌ λμ€ν¬λ¦½ν°λ₯Ό λ«μΌλ©΄ λ κ² κ°μ§λ§, μ€μ λ‘λ κ·Έλ κ² λ¨μνμ§ μλ€.
μλ₯Ό λ€μ΄, cmd1μ λͺ
λ Ήμ΄ indexκ° νμμ΄λ―λ‘ λ°λ³΅λ¬Έ λ΄μ fork μμ μ΄μ μ B νμ΄νλ₯Ό μμ±νκ² λ κ²μ΄λ€. κ·Έλ¦¬κ³ fork μ΄νμ μμ νλ‘μΈμ€μμλ B νμ΄νμ μνλ λ΄μ©μ κΈ°λ‘νκ² λ κ²μΈλ°, μ΄μ λν΄ νμν μΈμλ€μ A νμ΄νμμ μ½λλ‘ μ λν΄μΌ νλ€. μ΄μ λ°λ³΅λ¬Έμ μμ νλ‘μΈμ€μμλ A νμ΄νμ μ΄λ―Έ λ΄μ©μ κΈ°λ‘νμ κ²μ΄λ―λ‘ A νμ΄νμμ λ΄μ©μ μ½λλ°λ λ¬Έμ κ° μμ§λ§, λΆλͺ¨ νλ‘μΈμ€μμλ A νμ΄νμ λ΄μ©μ κΈ°λ‘νμ§ μμ κ²μ΄κΈ° λλ¬Έμ Writeμ λν νμΌ λμ€ν¬λ¦½ν°λ₯Ό λ«μ λμ΄μΌ νλ€. κ·ΈλμΌ ν fork μμ μ μμ νλ‘μΈμ€λ A νμ΄νμ λν΄μ Writeλ λ«ν μλ μνλ‘ Readλ₯Ό μννκ³ , μ΄λ € μλ Writeμ λν νμΌ λμ€ν¬λ¦½ν°κ° μμΌλ―λ‘ λκΈ° μμ΄ μ μ μ’
λ£λλ€.
cmd0λ μ½μ λ΄μ©μ΄ νμ΄νμ μλ κ²μ΄ μλλΌ νμΌμ μκ³ , κ°μ₯ λ§μ§λ§ cmdλ μΈ λ΄μ©μ΄ νμ΄νκ° μλλΌ νμΌμ μμΌλ―λ‘ λ κ²½μ°μ λν΄μλ λ³λμ μ²λ¦¬κ° νμνλ€.
νμν μμ λ§λ€ Writeμ λν νμΌ λμ€ν¬λ¦½ν°λ₯Ό μμ νλ‘μΈμ€μμ λ«μΌλ©΄ μ λλμ§ μλ¬Έμ΄ λ€ μ μλλ°, νμ΄νμ μ¬μ©νμ§ μμ Writeμ λν νμΌ λμ€ν¬λ¦½ν°λ₯Ό λ«λ κ³Όμ μ λΆλͺ¨ νλ‘μΈμ€μμλ νμνκΈ° λλ¬Έμ μ€λ³΅μΌλ‘ λ«λ ꡬ문μ λ£λ€κ°λ λκΈ°νλ₯Ό μ‘°κΈλ§ μλͺ»νλ©΄ Bad File Descriptorλ₯Ό λ³Ό μ μκ² λλ€. λ°λΌμ μ΅λν μμ νκ², fork μμ μ΄μ μ 곡ν΅μ μΌλ‘ μ²λ¦¬ν μ μλ λΆλΆμ λν΄μ λ¨Όμ μ²λ¦¬λ₯Ό ν΄μ£Όλ κ²μ΄ λ°λμ§νλ€.
μ λ΄μ©μ λν μμ§λ μ§μμ indexμ νμμ indexμ λͺ
λ Ήμ΄μμ μ¬μ©ν νμ΄νλ₯Ό μ μ ν μμ±νκ³ , μ¬μ©νμ§ μμ νμΌ λμ€ν¬λ¦½ν°μ λν΄μλ μ΄μ λ°λ³΅λ¬Έμμ μ¬μ μ μ²λ¦¬λ₯Ό ν΄μ€μΌ ν fork μμ μ λ¬Έμ κ° μλ€λ κ²μ΄λ€. μλ μμ¬ μ½λλ₯Ό νμΈν΄λ³΄μ.
int pipeA[2];
int pipeB[2];
int i;
pid_t pid;
i = -1;
while (++i < num_pipe + 1)
{
if (!(i % 2))
if (pipe(pipeA) < 0)
exit(1);
if (i % 2)
if (pipe(pipeB) < 0)
exit(1);
pid = fork();
if (pid == -1)
exit(1);
else if (!pid)
child_proc();
else
parent_proc();
}
/*
** child_proc
** (κ° κ³Όμ μ λν μ²λ¦¬μμ νμ μλ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ μ ν λ«λ κ³Όμ μ΄ νμνλ€.)
**
** μ΅μ΄: νμΌμμ μ½λ μμ
μ μν
**
** μ΅μ’
: νμΌμ μ°λ μμ
μ μν
**
** μ€κ°: μ§μ indexμΈμ§, νμ indexμΈμ§μ λ°λΌ μ΄λ νμ΄νμ Read, Writeλ₯Ό Redirectionν μ§ λ¬λΌμ§λ€.
** νμ index -> A νμ΄νμμ μ½μ΄μΌ νλ―λ‘ A νμ΄νμ Readλ₯Ό STDINμΌλ‘ dup2λ₯Ό μννλ€.
** B νμ΄νμ μ¨μΌ νλ―λ‘, B νμ΄νμ Writeλ₯Ό STDOUTμΌλ‘ dup2λ₯Ό μννλ€.
** μ§μ index -> B νμ΄νμμ μ½μ΄μΌ νλ―λ‘ B νμ΄νμ Readλ₯Ό STDINμΌλ‘ dup2λ₯Ό μννλ€.
** A νμ΄νμ μ¨μΌ νλ―λ‘, A νμ΄νμ Writeλ₯Ό STDOUTμΌλ‘ dup2λ₯Ό μννλ€.
*/
/*
** parent_procμ λͺ
λ Ήμ΄ indexμ λ°λ₯Έ μ²λ¦¬
** (ν indexμ μ²λ¦¬λ fork μμ μ΄ν μμ λͺ
μ¬νλ€.)
**
** μ΅μ΄: μ§μ indexμ΄κ³ μ½μ λ΄μ©μ νμΌμ μμΌλ―λ‘, A νμ΄νμ Writeλ§ λ«λλ€.
**
** μ΅μ’
: μ§μ indexμΈμ§, νμ indexμΈμ§μ λ°λΌ μ΄λ νμ΄νμ Writeλ₯Ό λ«λμ§ λ¬λΌμ§λ€.
** νμ index -> κΈ°μ‘΄μλ B νμ΄νμ Writeλ₯Ό νκ² μ§λ§, νμΌμ Writeλ₯Ό μνν κ²μ΄λ―λ‘ B νμ΄νμ Writeλ νμκ° μλ€.
** μ§μ index -> κΈ°μ‘΄μλ A νμ΄νμ Writeλ₯Ό νκ² μ§λ§, νμΌμ Writeλ₯Ό μνν κ²μ΄λ―λ‘ A νμ΄νμ Writeλ νμκ° μλ€.
**
** μ€κ°: μ§μ indexμΈμ§, νμ indexμΈμ§μ λ°λΌ μ΄λ νμ΄νμ Read, Writeλ₯Ό λ«λμ§ λ¬λΌμ§λ€.
** νμ index -> λ€μ λ°λ³΅λ¬Έμ μ§μ indexμ΄λ―λ‘ B νμ΄νμμ μ½κ³ , A νμ΄νμ μΈ κ²μ΄λ€.
** λ°λΌμ B νμ΄νμ Writeλ₯Ό λ«κ³ , A νμ΄νμ Readλ₯Ό λ«λλ€.
** μ§μ index -> λ€μ λ°λ³΅λ¬Έμ νμ indexμ΄λ―λ‘ A νμ΄νμμ μ½κ³ , B νμ΄νμ μΈ κ²μ΄λ€.
** λ°λΌμ A νμ΄νμ Writeλ₯Ό λ«κ³ , B νμ΄νμ Readλ₯Ό λ«λλ€.
**
** λͺ
λ Ήμ΄ indexμ λ°λ₯Έ μ²λ¦¬κ° λλ¬λ€λ©΄, μμ νλ‘μΈμ€μ ν λͺ
λ Ήμ΄ μνμ κΈ°λ€λ¦¬λλ‘ μ μ ν wait / waitpidλ₯Ό μ΄μ©νλ€.
** λ§μΌ μμ νλ‘μΈμ€μμ Exceptionμ΄ λ°μνλ€λ©΄, μ μ ν statusλ₯Ό λΆμνλ€.
** exec ν¨μλ μμ νλ‘μΈμ€ μ체λ₯Ό κ΅μ²΄νμ¬ μνλλ€λ μ μ μ μν΄μΌ νλ€.
*/
C
볡μ¬
μ μ½λλ₯Ό 보면 λ§μ§λ§ λͺ
λ Ήμ΄μ Readμ λν νμΌ λμ€ν¬λ¦½ν°κ° λ«νμ§ μμ κ²μ λ³Ό μ μλλ°, μ½λ ꡬλμ μμ΄μ λ¬Έμ κ° λλ κ²μ Writeμ λν νμΌ λμ€ν¬λ¦½ν°κ° λ«νμ§ μμ κ²½μ°μ΄λ€. νμ§λ§ κ·Έ μΈ μ€κ° λͺ
λ Ήμ΄μ νμΌ λμ€ν¬λ¦½ν°λ€μ Read, Writeμ λν΄ λ«λ κ²μ λ³Ό μ μλλ°, μ΄λ λμΌν λ²νΈμ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ μ§νκΈ° μν¨μ΄λ€. μ΄λ―Έ μ΄λ € μλ νμΌ λμ€ν¬λ¦½ν°λ₯Ό κ°κ³ μλ νμ΄νμ λ€μ pipeλ₯Ό μνν΄λ μ€λ₯λ λμ§ μμΌλ, κΈ°μ‘΄μ μ΄λ € μλ νμΌ λμ€ν¬λ¦½ν°μ λ²νΈλ₯Ό λ²λ¦¬κ³ μλ‘μ΄ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ»μ΄λ΄λ κ²μ λ³Ό μ μλ€. μ¦, μ€κ° λͺ
λ Ήμ΄μ λν΄μ νμ¬ μ¬μ© μ€μΈ νμ΄νμ νμΌ λμ€ν¬λ¦½ν°λ€μ μ μ ν λ«μμ£Όμ§ μμΌλ©΄ λμΌν λ²νΈμ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ μ§ν μ μκ² λλ€. μ΄μ κ°μ΄ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ μ§νλ κ²μ λ¬Έμ κ° λ κ°λ₯μ±μ΄ κ΅μ₯ν λμΌλ©°, νΉμ¬λ λμ μ체μλ λ¬Έμ μλλΌλ ν λΉ λ°μ νμΌ λμ€ν¬λ¦½ν°κ° μμ κ²½μ°κ° μμ μλ μλ€λ μ μ μ μν΄μΌ νλ€.
2) here_docμ λ°λ₯Έ μ¬μ©μ μ λ ₯ μ²λ¦¬
here_docμ λͺ
μνλ©΄ μ¬μ©μκ° μ§μ μ
λ ₯ν λ΄μ©μ νμ€ μ
λ ₯μΌλ‘ μ²λ¦¬νμ¬ λͺ
λ Ήμ΄κ° μ΄λ₯Ό λ°μ μ μλλ‘ λ§λ€μ΄μΌ νλ€. λ¨, ctrl + Dλ₯Ό μ΄μ©νμ§ μκ³ limiterμ ν΄λΉνλ λ¬Έμμ΄μ΄ λμ€λ©΄ νμ€ μ
λ ₯μ λ§μΉλλ‘ ν΄μΌνλ€. λ°λΌμ μλ¬΄λ° μμ
μμ΄ exec κ³μ΄ ν¨μκ° νμ€ μ
λ ₯μ μ΄μ©νκ² λ κ²½μ°μλ limiterμ λν ꡬλΆμ΄ λΆκ°λ₯νλ―λ‘ λ€λ₯Έ λ°©λ²μ΄ μꡬλλ€.
μ°μ get_next_lineμ μ΄μ©νμ¬ νμ€ μ
λ ₯μΌλ‘ limiter μ κΉμ§ λ°λλ‘ λ§λ€μ΄ λ΄κ³ μ΄λ₯Ό exec κ³μ΄ ν¨μκ° μ΄μ©ν μ μλλ‘ λ§λ€μ΄μΌ νλ€. μ΄ λ μ΄μ©ν μ μλ λ°©λ²μ 2κ°μ§κ° μλ€. 첫 μ§Έλ νμ΄νλ₯Ό μ΄μ©ν λ°©λ²μ΄κ³ , λ μ§Έλ μμ νμΌμ μ΄μ©ν λ°©λ²μ΄λ€.
νμ΄νλ₯Ό μ΄μ©νκ² λλ©΄ λ³λμ νμΌμ μ μ§νμ§ μμλ λκ³ , μ΄μ λν΄μ νλ‘κ·Έλ¨ μ’
λ£ μμ μ νμΌμ μμ νλ νμλ₯Ό κ±°μΉμ§ μμλ λλ€. νμ§λ§ νμ΄ν μμ²΄κ° μ μ§ν μ μλ λ°μ΄ν° μ체λ μ€μ μ λ°λΌ μ ν΄μ§ λ²νΌ μ¬μ΄μ¦ λ§νΌμ΄κΈ° λλ¬Έμ, νμ΄νλ₯Ό μ΄μ©νκΈ° μ μ νμ€ μ
λ ₯μ μ¬μ μ λ리λ μμ
μ΄ μꡬλλ€. κ·Έλ¦¬κ³ νμ€ μ
λ ₯μ μ¬μ μ λ리λ μμ
μ체λ λμΌ νλ‘μΈμ€μμ μ§ν μμ get_next_lineμΌλ‘ limiter μ κΉμ§ λ°μλ΄λ μμ
μ΄ λΆκ°λ₯νλ―λ‘, forkλ₯Ό ν΅ν΄ λ³λμ μμ νλ‘μΈμ€μμ μ§νν΄μΌ νλ€.
μμ νμΌμ μ΄μ©νκ² λλ©΄ λΉλ‘ νμΌμ λν κ΄λ¦¬κ° μꡬλκΈ΄ νλ, νμ΄νμ κ°μ΄ μ‘°κΈμ 볡μ‘ν κ³Όμ μ κ±°μΉμ§ μμλ λλ©° λ²νΌ μ¬μ΄μ¦ μ νμΌλ‘λΆν° μμ λ‘μ°λ―λ‘ λ°μ΄ν° ν¬κΈ°μ λν΄μ μ κ²½ μΈ νμκ° μμ΄μ§λ€. λ°λΌμ μ¬μ μ νμ€ μ
λ ₯μ λ릴 νμκ° μμ΄μ§λ―λ‘, fork μμ
μ΄ μꡬλμ§ μλλ€.
pipexμμ unlink ν¨μλ₯Ό νμ©νμ§λ§ μμ§κΉμ§ μ¬μ©μ΄ λμ§ μμκΈ° λλ¬Έμ unlink ν¨μλ₯Ό μ¬κΈ°μ μ¬μ©νλ©΄ λκ² λ€λ μκ°μ΄ λ€μκ³ , νμ΄νλ₯Ό μ΄μ©νμ¬ νμ€ μ
λ ₯μ λλ € λλ μμ
μ΄ λͺ
λ Ήμ΄ μ€ν μ μ μ΄λ€μ Έ λΉλ‘ λͺ
λ Ήμ΄ μ€ν μ μ΄λΌ μ½νμ§λ μμΌλ μ κ·Όμ΄ κ°λ₯νλ€λ μ λλ¬Έμ limiterμ μλ―Έμλ μ‘°κΈ κ±°λ¦¬κ° μλ€λ μκ°μ΄ λ€μλ€. κ³ λ‘ λ λ°©λ² μ€ μ΄λ λ°©λ²μ μ¬μ©νμ¬λ 무방νλ€κ³ μκ°μ΄ λλ, μ¬λ¬ λ²λ³΅μ ν΅ν΄ μμ νμΌμ λ§λλ λ°©μμΌλ‘ μ§ννκΈ°λ‘ νλ€.
μ¬κΈ°κΉμ§ μκ°ν μ μλλ‘ λμμ£Όμ hyechoiλ, hyeonskiλ, hyeonsokλ κ°μ¬ν©λλ€.
1. νμ΄νλ₯Ό μ΄μ©ν here_doc μ²λ¦¬
1.
νμ΄ν μμ± ν fork μλ
2.
λΆλͺ¨ νλ‘μΈμ€ : νμ΄νμ Write λ«κΈ°
3.
λΆλͺ¨ νλ‘μΈμ€ : dup2λ₯Ό ν΅ν΄ νμ΄νμ Readλ₯Ό νμ€ μ
λ ₯μΌλ‘ λλ¦° ν, νμ΄νμ Read λ«κΈ°
4.
λΆλͺ¨ νλ‘μΈμ€ : λκΈ°
5.
μμ νλ‘μΈμ€ : νμ΄νμ Read λ«κΈ°
6.
μμ νλ‘μΈμ€ : get_next_lineμ ν΅ν΄ νμ€ μ
λ ₯μΌλ‘ μ½μ λ¬Έμμ΄μ νμ΄νμ Writeμ κΈ°λ‘
7.
μμ νλ‘μΈμ€ : limterλ₯Ό λ§λλ©΄ νμ΄νμ Write λ«κΈ°
8.
μμ νλ‘μΈμ€ : μ’
λ£
2. μμ νμΌμ μ΄μ©ν here_doc μ²λ¦¬
1.
O_WRONLY, O_CREAT, O_TRUNC λͺ¨λ λ° 0644 κΆνμΌλ‘ μμ νμΌ μμ±
2.
limiterκ° λμ€κΈ° μ κΉμ§ μμ νμΌμ κΈ°λ‘
3.
limiterλ₯Ό λ§λλ©΄ κΈ°λ‘μ μ€μ§νκ³ μμ νμΌμ λ«κΈ°
4.
O_RDONLY λͺ¨λλ‘ μμ νμΌ λ€μ μ΄κΈ°
5.
dup2λ₯Ό ν΅ν΄ νμ€ μ
λ ₯μ μμ νμΌλ‘ λ리기
6.
μμ νμΌ λ«κΈ°
3) κΈ°ν
μμμ μ²λ¦¬ν΄μΌ νλ λ΄μ©λ€ μΈμλ μλμ κ°μ΄ ν λ² μ―€μ μκ°ν΄λ΄μΌ νλ κ²λ€μ΄ μλ€.
1.
λ€μ€ λ°μ΄ν μ²λ¦¬
2.
λͺ
λ Ήμ΄ κ²½λ‘ μ€μ
3.
λͺ
λ Ήμ΄ μ²λ¦¬ λ¨μ
4.
μ€λ₯ 문ꡬ μ²λ¦¬
1λ²μ λν΄μ λ¨Όμ λμ¨ λ°μ΄ν μμ λ§μΆ°μ νμ±μ μ§νν΄μΌ νλ©°, λ°μ΄ν λ΄μ μμ§ μμ λ΄μ©λ€μ 곡백 λ¬Έμλ₯Ό κΈ°μ€μΌλ‘ νμ±μ μ§νν΄μΌ νλ€. μ΄ λ λ¨Όμ λ°κ²¬ν λ°μ΄ν μ μ체λ exec ν¨μμ μΈμλ‘ λκΈΈ λ ν¬ν¨ λμ΄μλ μ λλ€. μλ₯Ό λ€μ΄ awk '\"{count++} END {print count}\"'μ κ²½μ°, exec κ³μ΄ ν¨μμ μΈμλ‘λ awk, \"{count++} END {print count}\"μ κ°μ΄ λ°μ΄νλ₯Ό μ μΈνκ³ λ€μ΄κ°κ² λλ€.
μνν λͺ
λ Ήμ΄λ νμ /binμλ§ μλ κ²λ μλκ³ , /usr/binμλ§ μλ κ²λ μλλ€. μ ν΄μ§ λͺ
λ Ήμ΄λ₯Ό μ΄μ©ν μ μλ μν©λ μλκΈ° λλ¬Έμ λͺ
λ Ήμ΄μ λν κ²½λ‘λ₯Ό 미리 μ€μ ν΄λλ κ²μλ λ¬΄λ¦¬κ° μλ€. λ°λΌμ μ΅λν μμ λμκ³Ό μ μ¬νκ² μμ
μ ν΄μΌνλ―λ‘, μν©μ λ°λΌ μ μ ν κ²½λ‘μ λͺ
λ Ήμ΄λ₯Ό μ΄μ©ν μ μλλ‘ $PATHλ₯Ό μ΄μ©ν΄μΌ νλ€. μ΄μ λ°λΌ main ν¨μμμ μΈ λ²μ§Έ μΈμλ‘ char **envpλ₯Ό λ°λλ‘ λ§λ λ€. envpλ₯Ό ν΅ν΄ pipex ꡬλ μμ μ λͺ¨λ νκ²½ λ³μλ₯Ό μ»μ΄μλ€λ©΄, $PATHλΌλ νκ²½ λ³μλ₯Ό : λ¨μλ‘ νμ±μ νμ¬ μ κ·Όνλ €λ νμΌ μ΄λ¦μ λΆμ΄κ³ νμΌμ μ‘΄μ¬ μ 무λ₯Ό νμΈνλ©΄ λλ€. λ§μΌ νμΌμ΄ μ‘΄μ¬νμ§ μλλ€λ©΄ νμ±λ κ·Έ λ€μ κ²½λ‘λ₯Ό μ΄μ©νμ¬ νμΌμ μ‘΄μ¬ μ 무λ₯Ό νμΈνλ©΄ λκ³ , λκΉμ§ μ‘΄μ¬νμ§ μλλ€λ©΄ νμΌ μ΄λ¦ κ·Έλλ‘λ₯Ό μ΄μ©νλ€. μ΄μ κ°μ΄ μ€μ λ λͺ
λ Ήμ΄ κ²½λ‘λ₯Ό μ΄μ©νμ¬ exec κ³μ΄ ν¨μλ‘ μ€νμ νμ λ μ€λ₯κ° λ°μνλ€λ©΄, μμμμ λ€μν μ€λ₯ ꡬ문과 μ μ¬νκ² μ μ ν μμ
μ΄ μꡬλλ κ²μ μμ΄μ μ λλ€.
κ²°κ΅μ $PATH νκ²½ λ³μλ₯Ό μ΄μ©νλ©΄μ execvpλ₯Ό μ΄μ©νμ§ μλ μ΄μ λ, execvpλ pipex ꡬλ λμ€ λ³κ²½λ $PATHμ λν΄μλ μν₯μ λ°μ μ μκΈ° λλ¬Έμ΄λ€. μ΄λ $PATH Injection AttackμΌλ‘ μ΄μ΄μ§ μ μμ΄ μλμ μΌλ‘ λ 보μμ μ·¨μ½νλ€.
3λ²μ λν΄μ κ°κ³ΌνκΈ° μ¬μ΄ κ² κ°λ€λ μκ°μ΄ λ€μλ€. μ²μμ pipexλ₯Ό ꡬνν λ νμ΄νλ‘ λμ΄κ°κΈ° μ μ μ€λ₯κ° λλ©΄ μ 체 νλ‘κ·Έλ¨μ μ’
λ£νλ λ°©μμ κ³ μ§νλλ°, μ€μ μμμλ νμ΄νλ‘ κ΅¬λΆλ λͺ
λ Ήμ΄λ€ μ¬μ΄μ μ€λ₯κ° μκΈ°λ©΄ μ¦μ μ’
λ£λμ§ μκ³ νμ΄ν λ¨μλ‘ λλ λͺ
λ Ήμ΄λ€μ λͺ¨λ μ²λ¦¬νλ κ²μ λ³Ό μ μμλ€. μλ₯Ό λ€μ΄μ grep hello | wc -l κ³Ό κ°μ 2κ°μ λͺ
λ Ήμ΄κ° μλ€κ³ ν΄λ³΄λ©΄, grepμμ μ€λ₯κ° λλ€κ³ ν΄μ μ’
λ£λλ κ²μ΄ μλλΌ grepμμ μ€λ₯κ° λλλΌλ wcλ λ€μ΄μ€λ μΈμκ° μλ κ²μΌλ‘ μκ°νκ³ μ μμ μΌλ‘ λμνλ€λ κ²μ΄λ€. μ¦, νμ΄νλ₯Ό μ΄μ©νκ² λλ©΄ λͺ
λ Ήμ΄ μ²λ¦¬ λ¨μλ μ μ²΄κ° μλ νμ΄ν λ¨μμμ λͺ
μ¬ν΄μΌ νλ€.
μμ λν΄μ bash νΉμ zshλ₯Ό λ§μ΄ μ΄μ©νλ€. λ체μ μΌλ‘ λ μμμ λ΄λ μ€λ₯ 문ꡬλ€μ΄ λΉμ·νκ±°λ λμΌν κ²½μ°κ° λ§μμ, μ€λ₯ 문ꡬμ λν΄μλ μ νν λ§μΆ°μΌ νλκ°μ λν΄ κ³ λ―Όμ΄ λ€ μλ μκ² λ€λ μκ°μ΄ λ€μλ€. νμ§λ§ μμ bash, zshλ§ μλ κ²μ μλλ€. λ μ μΈμλ sh, csh, ksh, tcsh λ± λ€μν μμ΄ μ‘΄μ¬νλ€. μ΄ μλ€ λ΄μμλ λͺ¨λ μ€λ₯ λ¬Έκ΅¬κ° λμΌνμ§λ μλ€. μ μκ°ν΄λ³΄λ©΄ μ΄λ€λ μλ‘ λ€λ₯Έ κ°λ°μλ€μ μν΄ λ§λ€μ΄μ§ μλ‘ λ€λ₯Έ νλ‘κ·Έλ¨μ λΆκ³Όνλ€. μ€λ₯μ λν μ²λ¦¬κ° λμλ€λ μ μ λμΌνμ§λ§ λͺ¨λ λ¬Έκ΅¬κ° μΌμΉνμ§λ μλλ€. λ°λΌμ pipexλ₯Ό ꡬνν λλ λ§₯λ½ μ μ΄λ€ μ€λ₯κ° λ°μνλμ§ νμ
λ§ κ°λ₯νλ€λ©΄ μ€λ₯ λ¬Έκ΅¬κ° λ¬λΌλ ν¬κ² λ¬Έμ κ° μλ€λ μκ°μ΄ λ λ€. νΉν pipexμμλ λͺ¨λ 문ꡬλ₯Ό λ§μΆκ³ μ νλ€λ©΄ μΈμκ° λλ ν 리μΈμ§ μλμ§μ λν ꡬλΆμ΄ νμν λκ° μλλ°, pipexμμλ <sys/stat.h>μ stat ꡬ쑰체μ κ΄λ ¨ ν¨μλ€μ΄ νμ©λμ§ μμκΈ° λλ¬Έμ μ ννκ² λ¬Έκ΅¬λ₯Ό λ§μΆλλ°λ λ¬΄λ¦¬κ° μλ€. μ²λ¦¬κ° λΆκ°λ₯ν 문ꡬ μΈμλ μ΅λν μ€λ₯μ λν μλ―Έ μ λ¬μ΄ κ°λ₯νλλ‘ λ§λ€μ΄μΌ νλ€.
3. Reference
κ³ λ €λνκ΅ COSE341 μ΄μ체μ by μ ν κ΅μλ