programing

POSIX 시스템에서는 argc를 0으로 할 수 있습니까?

javaba 2022. 7. 17. 11:33
반응형

POSIX 시스템에서는 argc를 0으로 할 수 있습니까?

메인 프로그램의 표준 정의:

int main(int argc, char *argv[]) {
   ...
}

에서 '''를 할 수 있는가''argcPOSIX는?

네, 가능합니다.프로그램을 다음과 같이 호출하는 경우:

execl("./myprog", NULL, (char *)NULL);

또는 다음 중 하나를 선택합니다.

char *args[] = { NULL };
execv("./myprog", args);

'에서는 'myprog'로 .argc0이 .

표준에서는 특히 0이 허용됩니다.argc호스트 환경에서의 프로그램 부팅에 대해서는 섹션 5.1.2.1에서 설명한 바와 같이 다음과 같습니다.

1 프로그램 부팅 시 호출되는 함수의 이름이 지정됩니다.main구현에서는 이 함수에 대한 프로토타입이 없음을 선언합니다.은 「돌아가다」로해야 합니다.int다음 중 하나:

int main(void) { /* ... */ } 

2개의 서는 「2」로 를합니다.argc ★★★★★★★★★★★★★★★★★」argv수 이기 때문에 할 수 있습니다 : , 、 , 、 의 、 의 、 의 、 의 、 임 , , , , , 。이는 선언된 함수의 로컬이기 때문입니다).

int main(int argc, char *argv[]) { /* ... */ }

또는 동등한 것, 또는 다른 구현 정의 방식.

2 선언된 경우 파라미터는main기능은 다음과 같은 제약을 준수해야 한다.

  • 「」의 값argc음이 아니어야 한다.
  • argv[argc].

...

이은 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, argc이 됩니다.argv[0] NULL을 사용하는가.printf는 NULL 포인터를 NULL 때합니다.%s되어 있지 .이 경우 많은 구현에서 "(null)"이 출력되지만 보장되지는 않습니다.

다른 답변에 덧붙이자면 C(POSIX 여부)에는 main()이 프로그램 내의 함수로 호출되는 것을 방해하는 것이 없습니다.

int main(int argc, int argv[]) {
    if (argc == 0) printf("Hey!\n");
    else main(0,NULL);

    return 0;
}

이 될 수 요. 즉, 0은 0, 0은 0, 0은 0이 될 수도 있고,argv[0] == NULL.

은 관습이다argv[0]프로그램 이름입니다.당신은 가질 수 있다argc == 0이그제큐티브 패밀리와 같이 어떤 논쟁도 하지 않고 2진법을 실행한다면요프로그램 이름과는 전혀 다른 문자열을 지정할 수도 있습니다.그렇기 때문에argv[0]프로그램 이름을 얻는 것이 전적으로 신뢰할 수 있는 것은 아닙니다.

일반적으로 명령줄을 입력하는 셸은 항상 첫 번째 인수로 프로그램 이름을 추가하지만 이는 규칙입니다. ifargv[0]== "--help" 및 getopt to parse 옵션을 사용하면 다음과 같은 이유로 검출되지 않습니다.optind1 을 할 수 있습니다.optind으로 , 0 을 사용합니다.getopt도움말

거두절미 이것은 완벽하게 긴는 이야기가 가능하다:그것은 완벽하게 가능하다.argc == 0((argv[0]정말 자기 자신에 의해 특별하지 않나.그 자체로는 별로 특별하지 않다.)는 발사기 전혀 논쟁을 주지 않는다 그것은 일어난다.런처가 인수를 전혀 제공하지 않을 때 발생합니다.

초기 제안에서는 main()에 전달된 argc 값이 "하나 이상"이어야 했습니다.이는 ISO C 표준의 초안에서 동일한 요건에 의해 추진되었다.실제로 exec 함수의 호출자에게 인수가 제공되지 않는 경우 이력 구현은 값 0을 넘겼습니다.이 요건은 ISO C 표준에서 삭제되었으며 이후 이 볼륨 POSIX.1-2017에서도 삭제되었습니다.특히 이 단어를 사용하기 위해서는 엄밀하게 준거한 POSIX 어플리케이션이 exec 함수에 적어도1개의 인수를 전달해야 합니다.따라서 argc가 이러한 어플리케이션에 의해 호출되었을 때 1개 이상임을 보증합니다.실제로 기존 어플리케이션의 대부분은 argc 값을 먼저 확인하지 않고 argv[0]를 참조하기 때문에 이는 좋은 프랙티스입니다.

또한 Strictly Conforming POSIX Application의 요건에서는 첫 번째 인수로 전달된 값이 시작 중인 프로세스와 관련된 파일 이름 문자열임을 명시하고 있습니다.일부 기존 응용 프로그램은 파일 이름 문자열이 아닌 경로 이름을 전달하지만 argv[0]의 일반적인 용도는 인쇄 진단에 있기 때문에 파일 이름 문자열이 더 일반적으로 유용합니다.전달된 파일명이 파일의 실제 파일명이 아닌 경우가 있습니다.예를 들어 로그인 유틸리티의 많은 구현에서는 실제 파일명에 프리픽스('-')를 붙이는 규칙을 사용하고 있습니다.이는 명령어인터프리터가 호출되고 있음을 나타냅니다.

또한 test 및 [유틸리티]에는 argv[0] 인수에 특정 문자열이 필요합니다.이러한 문자열은 모든 구현에 주의해 주십시오.

원천


POSIX 시스템에서는 argc를 0으로 할 수 있습니까?

네, 하지만 POSIX에 엄밀하게 준거하고 있지는 않을 것입니다.

때마다실행파일을 실행할 때마다 같은 다음과 좋아하는 실행 파일 운영하고 싶어../a.out그것은 하나의 논쟁가질 것이다 논거를은그것은 하나읠 땐 할 것이다.그것은 그 것이다.program name. 하지만 그건 그러나 프로그램을실행하는 것은 가능하다. 프로그램과 운전할 수 있다.argc~하듯이로zero리눅스에서는,를 호출하는 다른 프로그램에서 그것을 실행함으로써 를 호출하는다른 프로그램에서 실행함으로써.execv한 와 함께와empty argument list.

예를 들어

int main() {
    char *buf[] = { NULL };
    execv("./exe", buf); /* exe is binary which it run with 0 argument */
    return 0;
}

TL, DR:네, TL, DR:네,argv[0]될 수 있다고 NULL 것은 아니지만 내가 알고 있는 어떤good/sane 이유로.NULL일 수도 있지만, 제가 알기로는 좋은 이유나 나쁜 이유가 없습니다. 만약 그렇다 하더라도 치 않을 .argv[0]는 NULL이며, 특히 프로세스가 크래시할 경우 이를 허용합니다.


네.argv[0]는 인수 없이 실행된 경우에만 POSIX 시스템에서 NULL이 될 수 있습니다.

더 흥미로운 실용적인 질문은 프로그램이 관심을 가질 인가 하는 입니다.

이에 대한 답은 "아니요, 당신의 프로그램은 argv[0] 는 NULL이 아닙니다.일부 시스템 유틸리티(명령줄 유틸리티)가 동작하지 않거나 비결정적인 방법으로 동작하기 때문입니다.argv[0] == NULL그러나, 보다 중요한 것은, 어떠한 프로세스도 그것을 실행할 수 있는 타당한 이유(우둔함이나 악의에 찬 목적 이외에는)가 없다는 것입니다.(그때도 표준적인 사용방법이 실패했을지는 모르겠지만, 효과가 있을 것이라고는 생각하지 않습니다.)

많은 코드, 그리고 실제로 제가 쓰는 대부분의 예와 유틸리티는 다음과 같은 것으로 시작됩니다.

int main(int argc, char *argv[])
{
    if (argc < 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
        printf("Usage: %s [ -h | --help ]\n", argv[0]);
        /* ... print usage ... */
        return EXIT_SUCCESS;
    }

또, 적어도 명령어 패스를 제공하지 않고는 다른 프로세스를 실행할 정당한 이유가 없기 때문에, 이것은 합리적이고 받아들일 수 있습니다.execlp(cmd, cmd, NULL)보다는execlp(cmd, NULL).

(단, 파이프 또는 소켓명령어와 관련된 타이밍 레이스 윈도우의 부정 이용 등 몇 가지 이유를 생각할 수 있습니다.악질적인 프로세스는 확립된 Unix 도메인소켓 경유로 악의적인 요구를 송신한 후 즉시 허가된 피해자 명령으로 대체됩니다(인수 없이 실행되어 기동 시간을 최소한으로 합니다).이 경우,요청을 받은 서비스는 피어 credential을 체크하고 원래 악의적인 프로세스가 아닌 suppid 명령을 확인합니다.내 생각에, 그러한 피해자의 명령은 강하고 빠르게 충돌하는 것이 최선이다.SIGSEGV(NULL 포인터를 참조함으로써) "착하게" 행동하기보다는 악의적인 프로세스에 더 큰 시간 창을 부여합니다.)

즉, 프로세스가 자신을 다른 프로세스로 치환할 는 있지만 원인이 되는 인수는 없습니다.argc제로가 되는 것은, 그러한 행위가 불합리하며, 그렇게 하는 것에 대해 알려진 악의적이지 않은 이유가 없다는 엄밀한 의미에서는 불합리하다.

이것 때문에, 그리고 내가 악의적이고 배려심이 없는 프로그래머들과 그들의 프로그램들의 삶을 힘들게 하는 것을 좋아한다는 사실 때문에, 나는 개인적으로 다음과 같은 사소한 체크는 절대 추가하지 않을 것이다.

static int usage(const char *argv0)
{
    /* Print usage using argv0 as if it was argv[0] */
    return EXIT_SUCCESS;
}

int main(int argc, char *argv[])
{
    if (argc < 1)
        return usage("(this)");
    if (argc < 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
        return usage(argv[0]);

    /* argv[0] and argv[1] are non-NULL, argc >= 2 */

단, 특정 기존 사용 사례를 염두에 둔 누군가가 요청한 경우는 예외입니다.그래도 좀 의심스러울 것 같아서 먼저 사용 사례를 직접 확인하고 싶습니다.

언급URL : https://stackoverflow.com/questions/49817316/can-argc-be-zero-on-a-posix-system

반응형