it-source

argv[0]는 언제 null을 가질 수 있습니까?

criticalcode 2023. 9. 18. 21:31
반응형

argv[0]는 언제 null을 가질 수 있습니까?

논쟁을 전달하는 것에 대해 제가 이해하고 있는 것은main()령면면tm령eargc의을다다a를 가집니다.1그리고.argv[0]항상 프로그램 이름에 경로가 포함되어 있습니다.

되면 에 가 되는 되는 argc보다 ≥ 1 ≥ ≥ ≥ ≥ ≥ ≥ ≤argv[1]argv[argc-1]그런 논쟁이 있을 겁니다

이 링크의 한 단락은 다음과 같이 말합니다.

argv[0]프로그램 이름을 포함하는 문자열이거나 사용할 수 없는 경우 null 문자열이 됩니다.

지금, 언제 어떻게 할 수 있을까요?argv[0] string??제 말은 그 경로를 가진 프로그램 이름은 항상 사용 가능할 것인데 언제 null이 될 수 있나요?

작성자는 "그것을 사용할 수 없는 경우"라고 말하지만 프로그램 이름을 언제, 어떻게 사용할 수 없는 것이 가능합니까?

exec호출 클래스, 프로그램 이름과 프로그램 실행 파일을 별도로 지정하면 NULL로 설정할 수 있습니다.

그러나 이 인용문은 실제로 ISO 표준에서 나온 것이며(아마도 의역), 이 표준은 가장 작은 마이크로컨트롤러부터 최신 z10 Enterprise급 메인프레임에 이르기까지 매우 광범위한 실행 환경을 다룹니다.

대부분의 임베디드 시스템은 실행 가능한 이름이 거의 의미가 없는 상황에 놓여 있을 것입니다.

최신 c1x 초안에서:

의 의 값.argc음이 아니어야 합니다.

argv[argc]널 포인터여야 합니다.

의 이 가 가 의 argc, 부재 0큼,버열argv[0]를 통하여argv[argc-1]포함은 프로그램 시작 전에 호스트 환경에 의해 구현 정의 값이 제공되는 문자열에 대한 포인터를 포함해야 합니다.

이 말은 만약argc할 수 있음) NULL입니다. argv[0]는 NULL입니다이은 argv[0는 NULL입니다

, 가 argc는 0이 아닙니다. 표준에도 다음과 같이 명시되어 있으므로 프로그램 이름을 얻을 수 없습니다.

의 이 가 가 의 argc0보다 , 은 0π π, π π로 가리킵니다.argv[0]는 이름을 .램을다다을램sse;e .argv[0][0]호스트 환경에서 프로그램 이름을 사용할 수 없는 경우 null 문자가 됩니다.의 면가면가effe의면argc, 은 1π로 . 문자열이 가리키는argv[1]를 통하여argv[argc-1]프로그램 파라미터를 나타냅니다.

따라서 표준에 따라 프로그램 이름을 제공할 필요가 없습니다.프로그램이 이 값에 대해 다양한 옵션을 사용하는 것을 본 적이 값은 다음과 같습니다.

  • (보안에 대한) 값이 전혀 없습니다.
  • 거짓말 (예: )sleep악의적인 코드 조각에 대해.
  • 이름: :sleep).
  • 약간 변형된 것( 등)-ksh(로그인 셸의 경우).
  • 이름 (예: :progname - a program for something).

한 의 실행 가능한 예argv[0] == NULL

발신자

#define _XOPEN_SOURCE 700
#include <unistd.h>

int main(void) {
    char *argv[] = {NULL};
    char *envp[] = {NULL};
    execve("callee.out", argv, envp);
}

부름의

#include <stdio.h>

int main(int argc, char **argv) {
    if (argc == 0 && argv[0] == NULL)
        puts("yup");
}

그러면:

gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o caller.out caller.c
gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o callee.out callee.c
./caller.out

출력:

yup

빈 인수 목록으로 기존 프로그램 테스트

다음은 path를 인수로 사용하고 arg가 없는 명령어로 실행하는 래퍼입니다.

발신자-애니씨

#include <unistd.h>
#include <stdio.h>

int main(int argc, char**argv) {
    char *empty[] = {NULL};
    execve(argv[1], empty, empty);

}

샘플 사용량:

./caller-any.out /bin/ls

는 GNU Coreutils와 같은 도구입니다.ls그러나 수표를 가지고 있습니다argv[0]다음 위치에서 언급된 NULL:execeve 시스템 호출이 argv 인수 없이 "/bin/sh"만 실행하고 "/bin/ls"는 실행하지 못하는 이유는 무엇입니까?ls출력:

A NULL argv[0] was passed through an exec system call.
Aborted (core dumped)

Ubuntu 19.04에서 테스트되었습니다.

이 메일링 리스트에 의하면,argv[0]우 null일수다수efn의우l일eargc == 0. 하지만 그들은 언제가 언제인지 설명하지 않습니다. argc0일 수도 있습니다.내가 의심할 입니다. argc 명령줄을 행 행 지 "은 "황 "즉 "을 "해 "에서는 "이 "이 "될 "입니다 ", "을 "에서는 "즉 "이 ") "해 "지 "0 "" "" "입니다 0 "될 "d "행 " " " 0 " "popen -- 언급했듯이,으로 설정할 수 , ) -- @yonhdiablo 한 할 으로 처럼 할 한 으로 처럼 argv기능군들과 함께라면argc그러한 인수에 따라 0이 될 수 있습니다.

그러나 근거 섹션에서는 다음과 같이 설명합니다.

은 과 했습니다 를 은 했습니다 의 값을 했습니다.argc에게 main()"하나 또는 그 이상"이 됩니다.이는 ISO C 표준 초안의 동일한 요구 사항에 의해 추진되었습니다.실제로 과거 구현은 exec 기능의 호출자에게 인수가 제공되지 않을 때 0의 값을 전달했습니다.이 요구사항은 ISO C 표준에서 제거되었으며 그 후 IEEE 규격 1003.1-2001의 이 볼륨에서도 제거되었습니다.이 에 적어도 의 인수를 ,히의게하는 POSIX이도다의을를로록에행은다g을et로록에구,행a이o,,gtf,snoddnneeysctecrees히tmx의argc해당 애플리케이션에 의해 호출될 때 하나 이상이 됩니다.많은 기존 애플리케이션이 이를 참조하기 때문에 이는 좋은 사례입니다.argv[0]의를지저고하지 argc.

하게 준수하는 프로그램에는 반드시 가 있어야 . 엄격하게 준수하는 POSIX 응용 프로그램은 다음을 수행해야 합니다.argc0보다 크지만, 그렇지 않으면 결코 보장되지 않습니다.

에 가 에 가 argc그리고.argv프로그램 시작 섹션에서 확인할 수 있습니다.

프로그램에 이름이 없는 플랫폼을 상상할 수 있습니다. 코드가 시작할 때 단순히 로드되는 것일 수도 있습니다.그것들에서 argv[0]은 NULL일 수 있습니다.C Standard에서는 argc 값을 0으로 허용하고 있으며 argv[argc]는 NULL이 되어야 합니다.

언급URL : https://stackoverflow.com/questions/2794150/when-can-argv0-have-null

반응형