exec - whdlgp/system_programming_pra GitHub Wiki
๋ฆฌ๋ ์ค ํ๊ฒฝ์์ ํ๋ก๊ทธ๋จ์ ํ๋ ๋ง๋ค๋ค ๋ณด๋ฉด ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์ ์คํ์์ผ์ผ ํ ๋๊ฐ ์๋ค. ์๋ฅผ ๋ค์ด์ ํ๋ก๊ทธ๋จ ๋ด์์ 'ps' ๊ฐ์๊ฑธ ์คํํด์ผ ํ๋ค๋ ์ง ๋ง์ด๋ค. ๋ค๋ฅธ ์ฌ๋๋ค์ fork๋ exec๋ฅผ ๋น๊ตํ๋๋ฐ, ๋์์ผ๋ก ๋ด์๋ ์ ๋น๊ต๊ฐ ๋๋์ง ๋๋ ๋ชจ๋ฅด๊ฒ ๋ค ใ กใ ก;
์ ๊ทธ๋ฆผ์ด ๋ญ ์๋ฆฌ๋๋ฉด, ์๋ ํ๋ก์ธ์ค๊ฐ ๋๋์ค exec ํจ์๋ฅผ ๋ง๋๋ฉด ๊ทธ์๋ฆฌ์์ ํธ์ถ๋ ํ๋ก์ธ์ค๊ฐ ๋์ ๋์๊ฐ๋ค. ์๋ ํ๋ก์ธ์ค๊ฐ ๋๋ค ๋ง๋ค๋ ์๋ฏธ. ๋ญ,,, ๋ค์์๋ ์์ ๋ฅผ ๋ณด๋ฉด ์๋ง ๋๋์ด ์ฌ๊บผ๋ค.
exec๋ ์ฐธ ๋๋ฝ๊ฒ ํจ์๊ฐ ๋ง๋ค. execl๋ ์๊ณ execlp๋ ์๊ณ ๋ญ,,, ์ฌ๊ธฐ์๋ ๋ฑ ๋๊ฐ์ง ํจ์๋ง ์๋ ค์ค๊บผ๋ค.
๊ทธ๋ ๊ฒ ๋ง์ด ์์์ ์ข์์ง๋๊ฒ ๊ฐ์ง๋ ์๊ณ ,,,
exec ๊ณ์ด ํจ์์๋ ๋ช๊ฐ์ง ๊ท์น์ด ์๋ค.
- v : ๋ฐฐ์ด ๋ฑ์ ์ด์ฉํ๊ฒ ๋จ ๋ป
- p : ์ฌ์ฉ์ PATH๋ก ์ง์ ๋ ๊ฒฝ๋ก์์ ๊ฒ์ํ๊ฒ ๋ค๋ ๋ป
- e : ํ๊ฒฝ๋ณ์๋ฅผ ํ๋ก๊ทธ๋จ์์ ์ค์ ํ ์ ์๋ค๋ ๋ป
์ฌ๊ธฐ์๋ e์ ๊ดํ ํจ์๋ ๋ค๋ฃจ์ง ์๋๋ค(๋ด๊ฐ ํ์๋ฅผ ๋ชป๋๋ผ๊ณ ์์ผ๋ฏ๋ก,,,).
execl(๊ฒฝ๋ก, ๋ช
๋ น, ๊ฐ,,, NULL)
๊ฐ๋ณ์ธ์๋ฅผ ์ฐ๋ ํจ์๋ค. execl์ ์ฌ์ฉํ ๊ฒฝ์ฐ์๋ ๋ช ๋ น(ํ๋ก๊ทธ๋จ)์ด ์์นํ ๊ฒฝ๋ก๊น์ง ๊ฐ์ด ์จ์ค์ผ ํ๋ค. ์๋ฅผ๋ค์ด echo ๋ช ๋ น์ด๋ฅผ ์จ์ hello๋ฅผ ์ถ๋ ฅ์ํจ๋ค๋ฉด
execl("/bin/echo", "echo", "hello", NULL);
๊ณผ ๊ฐ์ด ์จ์ฃผ๋ฉด ๋๋ค. ์ด๋ ๋ง์ง๋ง์ NULL์ ๋ฃ์ด์ค์ผ ํจ์ ์ฃผ์ํ์. ๋ํ execl์ ํธ์ถํ ์์ ์์ ๋ค์ ๋์ค๋ ๋ด์ฉ์ ์คํ๋์ง ์๋๋ค๋ ์ ๋ ์๊ฐํด๋์.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main(void)
{
printf("parent process start\n");
if(fork() == 0)
{
execl("/bin/echo", "echo", "hello", NULL); //echo๋ผ๋ ์ธ๋ถ ํ๋ก๊ทธ๋จ ์คํ
//๊ฒฝ๋ก ๋ช
๋ น ๊ฐ ๋ง์ง๋งNULL
fprintf(stderr, "failed");
exit(1);
}
sleep(1); //๋ถ๋ชจ์์ ๋๋๋ ์์ ๋ง์ถ๋ ค๊ณ
printf("parent process exit\n");
return 0;
}
parent process start
hello
parent process exit
์ ์์ ๋ execl์ ์ฌ์ฉ๋ฒ๊ณผ ํน์ง์ ๋จ์ ์ผ๋ก ๋ณด์ฌ์ฃผ๊ณ ์๋ค. ์์ ํ๋ก์ธ์ค๋ฅผ ํ๋ ๋ง๋ค์ด echo๋ช
๋ น์ด๋ฅผ ์คํ์ํค๋ ํ๋ก๊ทธ๋จ์ด๋ค.
์ด๋ ๋์ฌ๊ฒจ ๋ด์ผ ํ ์ ์ fprintf๋ฌธ๊ณผ exit๋ ์คํ๋์ง ์๋๋ค๋ ์ ์ด๋ค. execl์ด ์ ์์ ์ผ๋ก ๋์ํ์ง ์๋๋ค๋ฉด fprintf๋ฌธ์ด ์คํ๋๊ฒ ์ง๋ง, ์ ์์ ์ผ๋ก ์คํ๋๋ค๋ฉด ์คํ๋ ํ๋ก์ธ์ค๊ฐ ์๋ ํ๋ก์ธ์ค๋ฅผ ๋ฎ์ด์จ๋ฒ๋ฆด ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
ํ๊ฐ๋ฆฌ๋ ์ ์ ์์ํ๋ก์ธ์ค๊ฐ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ก ๋ฎ์ด์จ์ ธ ๋ฒ๋ ธ๋๋ฐ, wait์ waitpid ๊ฐ ๋์์ ํ ๊ฒ์ธ๊ฐ์ด๋ค. ๊ฒฐ๋ก ์ ์ผ๋ก ๋์ํ๋ค. ์๋ํ๋ฉด exec๋ก ํธ์ถ๋ ํจ์๋ ํธ์ถํ ํจ์์ ๊ฐ์ pid๋ฅผ ๊ฐ๊ธฐ ๋๋ฌธ์, ์์ ํ๋ก์ธ์ค๊ฐ ํธ์ถํ๋ค๋ฉด ์์ ํ๋ก์ธ์ค์ ๊ฐ์ pid๋ฅผ ๊ฐ๊ธฐ ๋๋ฌธ์ด๋ค.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
printf("parent process start\n");
if(fork() == 0)
{
execl("/bin/echo", "echo", "hello", NULL);
fprintf(stderr, "first fail");
sleep(1);
exit(1);
}
if(fork() == 0)
{
execl("/bin/date", "date", NULL);
fprintf(stderr, "second fail");
sleep(2);
exit(2);
}
if(fork() == 0)
{
execl("/bin/ls", "ls", "-l", NULL);
fprintf(stderr, "third fail");
sleep(3);
exit(3);
}
sleep(6);
printf("parent process finish\n");
return 0;
}
parent process start
hello
2016. 08. 02. (ํ) 11:49:12 KST
ํฉ๊ณ 16
-rwxrwxr-x 1 mongcom mongcom 8817 7์ 13 11:54 exec2
-rw-rw-r-- 1 mongcom mongcom 559 7์ 13 11:54 exec2.c
parent process finish
์ด ์์ ์์๋ ๋ถ๋ชจ ํ๋ก์ธ์ค์์ ์์ ํ๋ก์ธ์ค๋ฅผ ์ฌ๋ฌ๊ฐ ๋ง๋ค์ด ๋ด ์๋ก ๋ค๋ฅธ ๋ช ๋ น์ execl๋ก ํธ์ถ์ํจ๋ค. ๋์ผ๋ก ๋ณด๊ธฐ ํธํ๊ฒ ์์๋ฅผ ๋ง๋ค์ด์ฃผ๊ธฐ ์ํด sleep ํจ์๋ฅผ ์ฌ์ฉํ์๋ค. ์์ ์์ ๋ฅผ ๋ณด์๋ค๋ฉด execl ์ดํ์ fprintf, sleep, exit ๋ค์ ์คํ์ด ๋์ง ์์ ๊ฒ์์ ์์ํ ์ ์์ ๊ฒ์ด๋ค.
execvp(๋ช
๋ น, ๋ช
๋ น์ด์ ์ต์
๋ฐฐ์ด์ ํฌ์ธํฐ);
execvp๋ execl ๊ณผ ๋น์ทํ๋ฉด์ ์ข ๋ค๋ฅด๋ค. ์ฒซ์งธ๋ก๋ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋ช ๋ น์ด๋ง ์จ์ค๋ ๋๋ค๋ ์ ์ด๋ค. ์๋ํ๋ฉด ํ๊ฒฝ๋ณ์์์ ๋ช ๋ น์ด๋ฅผ ๊ฒ์ํ๋ ๊ณผ์ ๊น์ง ํฌํจํ๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ๋ค์๋ ๋ช ๋ น์ด์ ์ต์ ์ด ์ ์ฅ๋ ๋ฐฐ์ด์ ํฌ์ธํฐ๋ฅผ ๋๊ฒจ์ฃผ๋ฉด ๋๋ค. ๋ง๋ก ์ค๋ช ํ๋ ์ธ์ด์ ์ด์์ด ์๊ธด๊ฒ ๊ฐ๋ค;
๋ง์ฝ execvp ๋ผ๋ ํจ์๋ฅผ ์ด์ฉํด ps ์ ์ต์ -l ์ ์ฃผ์ด ์คํ์ํจ๋ค๋ฉด,
char* str[] = {"ps", "-l"}
execvp(str[1], &str[1]);
// ๋๋ execvp(str[1], str);
์ ๊ฐ์ด ์ฌ์ฉํ๋ฉด ๋๋ค.
์ฌํ exec ํจ์์ ๊ฐ์ด ํจ์๊ฐ ํธ์ถ๋ ์์ ์์ ์๋ ํ๋ก๊ทธ๋จ์ ๋ท ๋ด์ฉ์ ์คํ๋์ง ์๋๋ค.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <wait.h>
int main(int argc, char *argv[])
{
int child, pid, status;
pid = fork();
if(pid == 0)
{
execvp(argv[1], &argv[1]);
//๋ฌธ์์ด ๋ฌธ์์ด๋ค์ ๋ฐฐ์ด(์ฒซ๋ฒ์จฐ ๋ฌธ์์ด์ ํฌ์ธํฐ)
fprintf(stderr, "%s:failed\n", argv[1]);
}
else
{
child = wait(&status);
printf("[%d] child process %d finished", getpid(), child);
printf("\t exit code %d \n", status >> 8);
}
}
./exec3 ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1000 4107 4096 0 80 0 - 12717 sigsus pts/3 00:00:00 zsh
0 S 1000 5172 4107 0 80 0 - 1049 wait pts/3 00:00:00 exec3
4 R 1000 5173 5172 0 80 0 - 3859 - pts/3 00:00:00 ps
[5172] child process 5173 finished exit code 0
ps -l์ ์ธ์๋ก ์ฃผ์ด ์คํํด๋ณด์๋ค. execvp ๋ค์ ์๋ fprintf ๋ฌธ์ ์ญ์ ์คํ๋์ง ์์์ผ๋ฉฐ, ์คํ๋ ps๋ ์์ํ๋ก์ธ์ค์ ๊ฐ์ pid๋ฅผ ๊ฐ์ ธ wait ๊ฐ ๋์ํจ์ ํ์ธํ ์ ์๋ค.