Do You Coding?
[function] execve ํจ์ ์์๋ณด๊ธฐ ๋ณธ๋ฌธ

๐ ๋งค๋ด์ผ (Linux)
NAME
execve - execute program
: ํ๋ก๊ทธ๋จ์ ์คํ
SYNOPSIS
#include <unistd.h>
int execve(const char *pathname, char *const argv[], char *const envp[]);
DESCRIPTION
execve() executes the program referred to by pathname. This causes the program that is curโ
rently being run by the calling process to be replaced with a new program, with newly initialโ
ized stack, heap, and (initialized and uninitialized) data segments.
pathname must be either a binary executable, or a script starting with a line of the form:
#!interpreter [optional-arg]
argv is an array of pointers to strings passed to the new program as its command-line arguโ
ments. By convention, the first of these strings (i.e., argv[0]) should contain the filename
associated with the file being executed. The argv array must be terminated by a NULL pointer.
(Thus, in the new program, argv[argc] will be NULL.)
envp is an array of pointers to strings, conventionally of the form key=value, which are
passed as the environment of the new program. The envp array must be terminated by a NULL
pointer.
execve() does not return on success, and the text, initialized data, uninitialized data (bss),
and stack of the calling process are overwritten according to the contents of the newly loaded
program.
: execve()๋ pathname์ผ๋ก ์ธ๊ธ๋ ํ๋ก๊ทธ๋จ์ ์คํํฉ๋๋ค. ์ด๋ก ์ธํด ํ์ฌ ํธ์ถ ํ๋ก์ธ์ค์์
์คํ ์ค์ธ ํ๋ก๊ทธ๋จ์ด ์๋ก ์ด๊ธฐํ๋ ์คํ, ํ ๋ฐ (์ด๊ธฐํ ๋ฐ ์ด๊ธฐํ๋์ง ์์) ๋ฐ์ดํฐ ์ธ๊ทธ๋จผํธ๋ก
์ ํ๋ก๊ทธ๋จ์ผ๋ก ๋์ฒด๋ฉ๋๋ค.
pathname์ ์ด์ง ์คํ ํ์ผ์ด๊ฑฐ๋ #! interpreter [์ต์
-arg] ํ์์ ํ ํ์ผ๋ก ์์ํ๋ ์คํฌ๋ฆฝํธ์ฌ์ผ ํฉ๋๋ค.
argv๋ ์ ํ๋ก๊ทธ๋จ์ ๋ช
๋ น์ค ์ธ์๋ก ์ ๋ฌ๋๋ ๋ฌธ์์ด์ ํฌ์ธํฐ ๋ฐฐ์ด์
๋๋ค.
๊ด๋ก์ ์ผ๋ก ์ด๋ฌํ ๋ฌธ์์ด ์ค ์ฒซ ๋ฒ์งธ ๋ฌธ์์ด(์ฆ, argv[0])์ ์คํ ์ค์ธ ํ์ผ๊ณผ ๊ด๋ จ๋ ํ์ผ ์ด๋ฆ์ ํฌํจํด์ผ ํฉ๋๋ค.
argv ๋ฐฐ์ด์ NULL ํฌ์ธํฐ์ ์ํด ์ข
๋ฃ๋์ด์ผ ํฉ๋๋ค. (๋ฐ๋ผ์ ์ ํ๋ก๊ทธ๋จ์์ argv[argc]๋ NULL์ด ๋ฉ๋๋ค.)
envp๋ ์ผ๋ฐ์ ์ผ๋ก ์ ํ๋ก๊ทธ๋จ์ ํ๊ฒฝ์ผ๋ก ์ ๋ฌ๋๋ key=value ํํ์ ๋ฌธ์์ด์ ๋ํ ํฌ์ธํฐ ๋ฐฐ์ด์
๋๋ค.
envp ๋ฐฐ์ด์ NULL ํฌ์ธํฐ์ ์ํด ์ข
๋ฃ๋์ด์ผ ํฉ๋๋ค.
execve()๋ ์ฑ๊ณต ์ ๋ฐํ๋์ง ์์ผ๋ฉฐ, ์๋ก ๋ก๋๋ ํ๋ก๊ทธ๋จ์ ๋ด์ฉ์ ๋ฐ๋ผ ํ
์คํธ, ์ด๊ธฐํ๋ ๋ฐ์ดํฐ,
์ด๊ธฐํ๋์ง ์์ ๋ฐ์ดํฐ(bss), ํธ์ถ ํ๋ก์ธ์ค์ ์คํ์ ๋ฎ์ด์๋๋ค.
RETURN VALUE
On success, execve() does not return, on error -1 is returned, and errno is set appropriately.
: ์ฑ๊ณต ์ execve()๊ฐ ๋ฐํ๋์ง ์๊ณ , ์ค๋ฅ์ด๋ฉด -1์ด ๋ฐํ๋๋ฉฐ errno๊ฐ ์ ์ ํ๊ฒ ์ค์ ๋ฉ๋๋ค.
๐ ํจ์ ์ค๋ช
execve ํจ์๋ ๋ค๋ฅธ ํ๋ก๊ทธ๋จ(ex. ./a.out) ์ ์คํํ๊ณ , ์์ ํ๋ก๊ทธ๋จ์ ์ข ๋ฃ์ํค๋ ํจ์์ด๋ค.
์ธ์๋ก ๋ค์ด์จ path ์ฆ, ํ๋ก๊ทธ๋จ์ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ ธ์ ์คํํ๊ณ , argv์ ์ธ์ ๋ชฉ๋ก์ ๋ฐ์์ค๋ฉฐ,
envp์์ ํ๊ฒฝ ๋ณ์ ์ค์ ๋ชฉ๋ก์ ๊ฐ์ ธ์จ๋ค.
exec ๊ณ์ด ์ฌ๋ฌ ํจ์๋ค์ด ์กด์ฌ(execl, execlp, execle, execv, execvp ๋ฑ) ํ๋ฉฐ
execve๋ ๋ค๋ฅธ ํจ์๋ค๊ณผ ๋ค๋ฅด๊ฒ ํ๋ก๊ทธ๋จ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ ธ์ฌ ๋, ์ ์ฒด ๊ฒฝ๋ก ๋ช ์ ๊ฐ์ ธ์์ผํ๋ฉฐ,
์ธ์ ๋ฐฐ์ด์ ์ด์ค๋ฐฐ์ด๋ก ๊ฐ์ ธ์ค๊ณ , ํ๊ฒฝ ์ค์ ๋ ์ด์ค๋ฐฐ์ด๋ก ๊ฐ์ ธ์จ๋ค๋ ํน์ง์ด ์๋ค.
[ code_a.c ]
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
if (1 < argc)
printf("argv[1] = %s, getenv argv[1] = %s", argv[1], getenv(argv[1]));
return (0);
}
์ฐ์ code_a.c ์ด๋ค.
์ด ์ฝ๋๋ ์ถํ์ execve๋ก ๋ถ๋ฌ์ฌ ํ๋ก๊ทธ๋จ์ ์ฝ๋์ด๊ณ , argv๋ก ์ธ์๋ฅผ ๋ฐ์์ ์ฒ๋ฆฌํด์ฃผ๋ ๋จ์ํ ์ฝ๋์ด๋ค.
์ธ์๋ก ํ๊ฒฝ๋ณ์๋ฅผ ๋ฐ์์ getenv ํจ์์ ๋ฃ์ ๊ฑด๋ฐ, ์ด getenv ํจ์๋ ํ๊ฒฝ ๋ณ์๋ฅผ ๊ฒ์ํ์ฌ
ํด๋น ๋ฌธ์์ด ํฌ์ธํฐ๋ฅผ ๋ฆฌํดํด์ค๋ค.
> cc code_a.c -o show
> ./show HOME
| argv[1] = HOME, getenv argv[1] = /home/doyoucode |
์ถํ์ ํ๋ก๊ทธ๋จ์ show๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ถ๋ฌ์ค๊ธฐ ์ํด ์ปดํ์ผ ์ต์ ์ ํตํด ์ง์ ํด์ฃผ์๊ณ ,
./show ๋ก ์ฒซ๋ฒ์งธ ์ธ์๋ก HOME์ ๋ฃ๊ณ ์คํํ๊ฒ ๋๋ฉด, ํ๊ฒฝ๋ณ์ HOME๊ณผ ๊ทธ ํ๊ฒฝ๋ณ์์ ๊ฐ ๋ฌธ์์ด์ ์ถ๋ ฅํด์ค๋ค.
[ code_b.c ]
#include <stdio.h>
#include <unistd.h>
int main()
{
char *argv[] = { "./show", "DOYOU", NULL};
char *envp[] = { "DOYOU=dyomyo.tistory.com", NULL};
execve( "./show", argv, envp);
printf( "error\n");
return (0);
}
์ด์ , code_b.c๋ก ๋์ด๊ฐ๋ฉด,
execve์ ๋ฃ์ด์ค argv ๋ชฉ๋ก๊ณผ envp ๋ชฉ๋ก์ ์์ฑํด์ค ๊ฒ์ด๋ค.
๋ ์ด์ค ๋ฐฐ์ด์ ํญ์ NULL๋ก ๋๋ง์ณ์ผํ๋ฉฐ, ๊ทธ๋ ์ง ์์ผ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
์์ฑ ์, argv์๋ ์ธ์๋ฅผ ๋ฐ์์ฌ ๊ฒ์ธ๋ฐ, ์ฒซ ์ธ์๋ ๋ถ๋ฌ์ฌ ํ๋ก๊ทธ๋จ๋ช ์ผ๋ก ํ๋ค.
๊ทธ๋ฆฌ๊ณ , ๋๋ฒ์งธ ์ธ์๋ ํ๊ฒฝ๋ณ์๋ช ์ ๊ฐ์ ธ์ค๋๋ฐ, ์ง๊ธ์ envp์์ ํ๊ฒฝ์ค์ ์ ํตํด ๋ง๋ค 'DOYOU'๋ฅผ ๊ฐ์ ธ์จ๋ค.
envp์์๋ ์ฒซ ์ธ์๋ก ์ด 'DOYOU'์ ๊ฐ์ ์ง์ ํด์ ๋ฃ์ด์ฃผ๋ฉฐ, ๋ง์ฐฌ๊ฐ์ง๋ก NULL๋ก ๋ง๋ฌด๋ฆฌํ๋ค.
์ด๋ฌ๋ฉด ์ด์ execve์์ ํ๋ก๊ทธ๋จ ๊ฒฝ๋ก๋ช ๊ณผ ๋ง๋ค์ด๋ argv, envp๋ฅผ ๊ฐ์ ธ์ ์คํ์ ์์ผ์ฃผ๋๋ฐ,
์ ์์ ์ผ๋ก ์คํ์ด ๋๋ฉด ์ด ํ๋ก๊ทธ๋จ์ ์ข ๋ฃ๊ฐ ๋๊ณ ./show๊ฐ ์คํ์ด ๋๋ฉฐ, ๊ทธ๋ ์ง ์์ผ๋ฉด
ํ์ฌ ํ๋ก๊ทธ๋จ์ด ์งํ๋์ด printf("error\n"); ๊ฐ ์คํ๋ ๊ฒ์ด๋ค.
> cc code_b.c
> ./a.out
| argv[1] = DOYOU, getenv argv[1] = dyomyo.tistory.com |
๋ฐ๋ก cc๋ก ์ปดํ์ผ ํด์ ./a.out ์คํํ์ผ์ ๋ง๋ค์ด์ค ๋ค ์คํํ๋ฉด,
์ ์์ ์ผ๋ก ./show๊ฐ ์คํ๋์ด ์ฐ๋ฆฌ๊ฐ ์ ๋ฌํ argv์ ์ธ์ ๊ฐ์ด ์ ๋ฌ๋์ด ํด๋น ํ๊ฒฝ๋ณ์์ ๊ฐ์ด ์ถ๋ ฅ๋๋ค.
์ง๊ธ์ฒ๋ผ, ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์ ์ ์ ํ ์ธ์์ ํจ๊ป ํด๋น ์ธ์์ ํ๊ฒฝ ์ค์ ๊น์ง ์ ๋ฌํ์ฌ ์คํ์์ผ์ฃผ๋ ํจ์๊ฐ
execve์ด๋ฉฐ, ๋ค๋ฅธ exec ๊ณ์ด ํจ์๋ค์ ๋ค์ ์ธ์๋ค์ด ์กฐ๊ธ ๋ค๋ฅด๊ฒ ์ค์ ๋์ด ์๊ณ ์ผ๋ฐ์ ์ธ ๋์์ ๋น์ทํ๋ค.
'CS & Engineering > C' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [function] fork ํจ์ ์์๋ณด๊ธฐ (2) | 2024.06.04 |
|---|---|
| [function] exit ํจ์ ์์๋ณด๊ธฐ (0) | 2024.05.31 |
| [function] dup2 ํจ์ ์์๋ณด๊ธฐ (2) | 2024.05.28 |
| [function] dup ํจ์ ์์๋ณด๊ธฐ (0) | 2024.05.27 |
| [function] access ํจ์ ์์๋ณด๊ธฐ (0) | 2024.05.24 |