exec - whdlgp/system_programming_pra GitHub Wiki

๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์‹œํ‚ค๊ธฐ

๋ฆฌ๋ˆ…์Šค ํ™˜๊ฒฝ์—์„œ ํ”„๋กœ๊ทธ๋žจ์„ ํ•˜๋‚˜ ๋งŒ๋“ค๋‹ค ๋ณด๋ฉด ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰์‹œ์ผœ์•ผ ํ•  ๋•Œ๊ฐ€ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด์„œ ํ”„๋กœ๊ทธ๋žจ ๋‚ด์—์„œ 'ps' ๊ฐ™์€๊ฑธ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค๋“ ์ง€ ๋ง์ด๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์€ fork๋ž‘ exec๋ฅผ ๋น„๊ตํ•˜๋˜๋ฐ, ๋™์ž‘์œผ๋กœ ๋ด์„œ๋Š” ์™œ ๋น„๊ต๊ฐ€ ๋˜๋Š”์ง€ ๋‚˜๋Š” ๋ชจ๋ฅด๊ฒ ๋‹ค ใ…กใ…ก;

์œ„ ๊ทธ๋ฆผ์ด ๋ญ” ์†Œ๋ฆฌ๋ƒ๋ฉด, ์›๋ž˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋Œ๋˜์ค‘ exec ํ•จ์ˆ˜๋ฅผ ๋งŒ๋‚˜๋ฉด ๊ทธ์ž๋ฆฌ์—์„œ ํ˜ธ์ถœ๋œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋Œ€์‹  ๋Œ์•„๊ฐ„๋‹ค. ์›๋ž˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋Œ๋‹ค ๋งŒ๋‹ค๋Š” ์˜๋ฏธ. ๋ญ,,, ๋’ค์—์žˆ๋Š” ์˜ˆ์ œ๋ฅผ ๋ณด๋ฉด ์•„๋งˆ ๋Š๋‚Œ์ด ์˜ฌ๊บผ๋‹ค.

exec ํ•จ์ˆ˜๋“ค

exec๋Š” ์ฐธ ๋”๋Ÿฝ๊ฒŒ ํ•จ์ˆ˜๊ฐ€ ๋งŽ๋‹ค. execl๋„ ์žˆ๊ณ  execlp๋„ ์žˆ๊ณ  ๋ญ,,, ์—ฌ๊ธฐ์„œ๋Š” ๋”ฑ ๋‘๊ฐ€์ง€ ํ•จ์ˆ˜๋งŒ ์•Œ๋ ค์ค„๊บผ๋‹ค.
๊ทธ๋ ‡๊ฒŒ ๋งŽ์ด ์•Œ์•„์„œ ์ข‹์•„์ง€๋Š”๊ฒƒ ๊ฐ™์ง€๋„ ์•Š๊ณ ,,,

exec ๊ณ„์—ด ํ•จ์ˆ˜์—๋Š” ๋ช‡๊ฐ€์ง€ ๊ทœ์น™์ด ์žˆ๋‹ค.

  • v : ๋ฐฐ์—ด ๋“ฑ์„ ์ด์šฉํ•˜๊ฒ ๋‹จ ๋œป
  • p : ์‚ฌ์šฉ์ž PATH๋กœ ์ง€์ •๋œ ๊ฒฝ๋กœ์—์„œ ๊ฒ€์ƒ‰ํ•˜๊ฒ ๋‹ค๋Š” ๋œป
  • e : ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์„ค์ •ํ• ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป

์—ฌ๊ธฐ์„œ๋Š” e์— ๊ด€ํ•œ ํ•จ์ˆ˜๋Š” ๋‹ค๋ฃจ์ง€ ์•Š๋Š”๋‹ค(๋‚ด๊ฐ€ ํ•„์š”๋ฅผ ๋ชป๋Š๋ผ๊ณ  ์žˆ์œผ๋ฏ€๋กœ,,,).

execl

execl(๊ฒฝ๋กœ, ๋ช…๋ น, ๊ฐ’,,, NULL)

๊ฐ€๋ณ€์ธ์ž๋ฅผ ์“ฐ๋Š” ํ•จ์ˆ˜๋‹ค. execl์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ์—๋Š” ๋ช…๋ น(ํ”„๋กœ๊ทธ๋žจ)์ด ์œ„์น˜ํ•œ ๊ฒฝ๋กœ๊นŒ์ง€ ๊ฐ™์ด ์จ์ค˜์•ผ ํ•œ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด echo ๋ช…๋ น์–ด๋ฅผ ์จ์„œ hello๋ฅผ ์ถœ๋ ฅ์‹œํ‚จ๋‹ค๋ฉด

execl("/bin/echo", "echo", "hello", NULL);

๊ณผ ๊ฐ™์ด ์จ์ฃผ๋ฉด ๋œ๋‹ค. ์ด๋•Œ ๋งˆ์ง€๋ง‰์— NULL์„ ๋„ฃ์–ด์ค˜์•ผ ํ•จ์— ์ฃผ์˜ํ•˜์ž. ๋˜ํ•œ execl์„ ํ˜ธ์ถœํ•œ ์‹œ์ ์—์„œ ๋’ค์— ๋‚˜์˜ค๋Š” ๋‚ด์šฉ์€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ๋„ ์ƒ๊ฐํ•ด๋‘์ž.

/exec1/exec1.c

#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๋ฅผ ๊ฐ–๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

/exec2/exec2.c

#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(๋ช…๋ น, ๋ช…๋ น์–ด์™€ ์˜ต์…˜ ๋ฐฐ์—ด์˜ ํฌ์ธํ„ฐ);

execvp๋Š” execl ๊ณผ ๋น„์Šทํ•˜๋ฉด์„œ ์ข€ ๋‹ค๋ฅด๋‹ค. ์ฒซ์งธ๋กœ๋Š” ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ช…๋ น์–ด๋งŒ ์จ์ค˜๋„ ๋œ๋‹ค๋Š” ์ ์ด๋‹ค. ์™œ๋ƒํ•˜๋ฉด ํ™˜๊ฒฝ๋ณ€์ˆ˜์—์„œ ๋ช…๋ น์–ด๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ณผ์ •๊นŒ์ง€ ํฌํ•จํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋’ค์—๋Š” ๋ช…๋ น์–ด์™€ ์˜ต์…˜์ด ์ €์žฅ๋œ ๋ฐฐ์—ด์˜ ํฌ์ธํ„ฐ๋ฅผ ๋„˜๊ฒจ์ฃผ๋ฉด ๋œ๋‹ค. ๋ง๋กœ ์„ค๋ช…ํ•˜๋‹ˆ ์–ธ์–ด์— ์ด์ƒ์ด ์ƒ๊ธด๊ฒƒ ๊ฐ™๋‹ค;

๋งŒ์•ฝ execvp ๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ps ์™€ ์˜ต์…˜ -l ์„ ์ฃผ์–ด ์‹คํ–‰์‹œํ‚จ๋‹ค๋ฉด,

char* str[] = {"ps", "-l"}

execvp(str[1], &str[1]);
// ๋˜๋Š” execvp(str[1], str);

์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

์—ฌํƒ€ exec ํ•จ์ˆ˜์™€ ๊ฐ™์ด ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ ์‹œ์ ์—์„œ ์›๋ž˜ ํ”„๋กœ๊ทธ๋žจ์˜ ๋’ท ๋‚ด์šฉ์€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.

/exec3/exec3.c

#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 ๊ฐ€ ๋™์ž‘ํ•จ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ