
📌 매뉴얼 (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 계열 함수들은 뒤의 인자들이 조금 다르게 설정되어 있고 일반적인 동작은 비슷하다.
'프로그래밍 > 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 |