실행(시스템 호출)
exec (system call)
컴퓨팅에서, Exec은 이미 존재하는 프로세스의 맥락에서 실행 파일을 실행하는 운영 체제의 기능으로서, 이전 실행 파일을 대체한다. 이 행위를 오버레이라고도 한다. 다른 곳에 존재하지만 유닉스 같은 시스템에서는 특히 중요하다. 새로운 프로세스가 생성되지 않으므로 프로세스 식별자(PID)는 변경되지 않지만 프로세스의 시스템 코드, 데이터, 힙, 스택은 새 프로그램의 프로세스로 대체된다.
실행 전화는 컴파일 가능한 언어와 일부 스크립팅 언어를 포함한 많은 프로그래밍 언어에 사용할 수 있다. OS 명령 인터프리터에서는 셸 프로세스를 지정된 프로그램으로 대체하는 executive-in 명령.[1]
명명법
실행 및 실행 인터페이스는 다양하다. 프로그래밍 언어에 따라 하나 이상의 기능을 통해 액세스할 수 있으며, 운영 체제에 따라 하나 이상의 실제 시스템 호출로 표현될 수 있다. 이러한 이유로 임원은 때때로 함수의 집합으로 설명된다.
C에서 그러한 기능의 표준 명칭은 execl, execlp, execlp, execv, execeive, execvp(아래 참조)이지만, 그 자체는 "실행"하지 않는다. 리눅스 커널에는 "실행"이라는 이름의 해당 시스템 호출이 하나 있지만, 앞서 언급한 모든 기능은 그 주위에 사용자 공간 래퍼로 되어 있다.
상위 언어에서는 일반적으로 한 번의 호출 명명된 실행 기능을 제공한다.
Unix, POSIX 및 기타 멀티태스킹 시스템
C 언어 프로토타입
POSIX 표준은 실행자의 기능을 Unistd에서 선언한다.h 헤더 파일(C 언어). DOS(아래 참조), OS/2 및 Microsoft Windows에 대해 process.h에 동일한 기능이 선언되어 있다.
int execl(char const *path, char const *arg0, ...);
int execle(char const *path, char const *arg0, ..., char const *envp[]);
int execlp(char const *file, char const *arg0, ...);
int execv(char const *path, char const *argv[]);
int execve(char const *path, char const *argv[], char const *envp[]);
int execvp(char const *file, char const *argv[]);
일부 구현에서는 선도적인 밑줄(예: _execl)로 명명된 이러한 기능을 제공한다.
각각의 기본은 실행(실행)이며, 그 뒤에 하나 이상의 문자가 온다.
- e – 환경 변수에 대한 일련의 포인터가 새 프로세스 이미지에 명시적으로 전달된다.
- l – 명령줄 인수는 함수에 개별적으로 전달(목록)된다.
- p – PATH 환경 변수를 사용하여 실행할 파일 인수에 명명된 파일을 찾으십시오.
- v – 명령줄 인수는 포인터의 배열(벡터)으로 함수에 전달된다.
- 경로
인수는 새 프로세스 이미지로 실행할 파일의 경로 이름을 지정한다. arg0에서 시작하는 인수는 새로운 프로세스 이미지에 전달될 인수에 대한 포인터다. argv 값은 인수에 대한 포인터 배열이다.
- arg0
첫 번째 인수 arg0은 실행 파일의 이름이어야 한다. 일반적으로 경로 인수와 동일한 값이다. 일부 프로그램은 실행 파일의 위치를 제공하는 이 주장에 잘못 의존할 수 있지만, 이에 대한 보장은 없으며 플랫폼 전체에 걸쳐 표준화되지도 않는다.
- 부러워하다
인수 환경은 환경 설정에 대한 포인터 모음입니다. e로 끝나는 것으로 명명된 e는 환경 설정 목록을 envp 인수를 통해 전달함으로써 새로운 프로세스 이미지의 환경을 변경한다. 이 인수는 문자 포인터의 배열이며, 각 요소(최종 요소 제외)는 환경 변수를 정의하는 null 종단 문자열을 가리킨다.
각 null 종단 문자열의 형식:
name=value
여기서 이름은 환경 변수 이름이고 값은 해당 변수의 값이다. Envp 어레이의 최종 요소는 null이어야 한다.
execl, execlp, execv 및 execvp 호출에서 새 프로세스 이미지는 현재 환경 변수를 상속한다.
영향들
FD_CLOEXEC과 결부되거나 O_CLOEXEC과 함께 열리지 않는 한, 실행 호출을 할 때 열려 있는 파일 설명자는 새 프로세스 영상에서 열린 상태로 유지된다(후자는 POSIX.1-2001에서 소개됨). 이 측면은 새 프로그램의 표준 스트림(stdin, stdout 및 stderr)을 지정하는 데 사용된다.
중첩에 성공하면 프로세스의 이전 메모리 주소 공간이 파괴되고 공유되지 않은 모든 메모리 영역이 운영 체제에 의해 회수된다. 결과적으로, 새로운 프로그램에 전달되지 않았거나 저장되지 않은 모든 데이터는 손실된다.
반환값
성공한 임원은 현재 프로세스 이미지를 대체하므로, 호출한 프로그램에 어떤 것도 반환할 수 없다. 프로세스에는 종료 상태가 있지만 이 값은 상위 프로세스에 의해 수집된다.
실행 기능이 호출 프로그램에 복귀하면 오류가 발생하고 반환 값이 -1이며 오류는 다음 값 중 하나로 설정된다.
이름 | 메모들 |
---|---|
E2BIG | 인수 목록이 시스템 제한을 초과함. |
EACCES | 지정된 파일에 잠금 또는 공유 위반이 있음. |
에누엔트 | 파일 또는 경로 이름을 찾을 수 없음. |
에노엠 | 메모리가 부족하여 새 프로세스 이미지를 실행할 수 없음. |
DOS 운영 체제
DOS는 멀티태스킹 운영체제는 아니지만 가혹한 1차 메모리 한계와 가상 메모리 부족으로 인해 기존 실행 이미지를 대체하는 것이 큰 장점이 있다. DOS의 오버레이 프로그램에도 동일한 API가 사용되며 POSIX 시스템에도 비슷한 효과가 있다.
MS-DOS 실행 파일 헤더의 "최대 할당"이 기본값 0xFFFF로 설정된 것처럼 MS-DOS 실행 기능은 항상 새 프로그램을 메모리에 로드한다. EXEHDR 유틸리티를 사용하여 프로그램의 최대 할당 필드를 변경할 수 있다. 그러나 이 작업이 수행되고 프로그램이 실행 기능 중 하나로 호출되는 경우, 프로그램은 운영 체제 명령줄에서 직접 호출되거나 생성 기능 중 하나로 호출되는 프로그램과 다르게 동작할 수 있다(아래 참조).
명령 인터프리터
또한 많은 유닉스 셸은 셸 프로세스를 지정된 프로그램으로 대체하는 내장형 실행 명령을 제공한다.[1] 래퍼 스크립트는 환경 변수나 다른 구성을 설정한 후 직접 또는 인터프리터나 가상 시스템을 통해 프로그램을 실행하기 위해 이 명령을 사용하는 경우가 많다. 셸 프로그램이 사용하는 자원은 execute를 사용함으로써 프로그램 시작 후에도 계속 사용할 필요가 없다.[2]
또한 실행 명령은 리디렉션을 수행할 수 있다. 일부 쉘에서는 실제 오버레이를 하지 않고 리디렉션에만 실행 명령을 사용할 수도 있다.
대안
기존 유닉스 시스템에는 새로운 실행 프로그램을 한 번에 실행하는 새로운 프로세스를 만들 수 있는 기능이 없어 유닉스 프로그래밍에 대한 Exec의 중요성이 설명된다. 다른 시스템에서는 실행 파일을 실행하기 위한 주요 도구로 serven을 사용할 수 있다. 그 결과는 Unix 유사 시스템의 포크-실행 순서와 맞먹는다. POSIX는 일반적으로 vfork를 사용하여 구현되는 선택적 확장으로 posix_spawn 루틴을 지원한다.
기타 시스템
OS/360 및 후계자에는 Exec과 유사한 기능을 수행하는 시스템 호출 XCTL(Transfer Control)이 포함된다.
참고 항목
- 체인 로드, 시스템 프로그래밍의 오버레이
- 종료(시스템 호출), 프로세스 종료
- 포크(시스템 호출), 새 프로세스 만들기(단, 동일한 실행 파일 사용)
- 새 스레드를 생성하는 방법 복제
- PATH(변수), *경로 인수의 의미론과 관련됨
참조
- ^ Jump up to: a b "exec(3) - Linux manual page". man7.org. Retrieved 2016-10-14.
- ^ "Shell Wrappers". Linux Documentation Project. 2014-03-10. Retrieved 2021-02-18.
외부 링크
- 단일 UNIX 사양, Open Group의 문제 7 : 파일 실행 – 시스템 인터페이스 참조,