“argv [0] = name-of-executable”이 허용되는 표준입니까 아니면 일반적인 규칙입니까?
main()
C 또는 C ++ 응용 프로그램에서 인수를받을 때 argv[0]
항상 실행 파일의 이름이 검증됩니까? 아니면 이것이 일반적인 관례 일 뿐이며 100 % 진실이라고 보장되지 않는 보장입니까?
추측 (교육을받은 추측 작업 포함)은 재미를 추측하는 작업 표준 문서로 이동해야합니다. 예를 들어 ISO C11은 다음과 같이 (내 강조).
의 값
argc
이 0 크면로 많고은 프로그램 이름 을argv[0]
나타냅니다 .argv[0][0]
호스트 환경에서 프로그램 이름을 사용할 수없는 경우 널 문자가됩니다.
따라서 해당 이름을 사용할 수있는 경우 에만 프로그램 이름 입니다. 그것은 그리고 프로그램 이름을 "나타내고" , 프로그램 이름 일 반드시 필요 는 없습니다 . 그 앞의 섹션은 다음과 가변적이다.
값의
argc
이 0보다 크면 포함를argv[0]
통한 배열 구성원argv[argc-1]
은 프로그램 시작 전에 호스트 Environmental &에서 구현 정의 값을 제공하는 문자열에, 대한 포인터를 포함합니다.
이는 C99에서 변경되지 않는 현상, 값 조차도 표준에 의해 지시되지 않습니다 . 이는 전적으로 구현에 달려 있습니다.
Environmental &이 경우 호스트 수단은 프로그램 이름이 비어있을 수 없는 호스트 Environmental &이 경우를 제공하고, 아무것도 하지 "무엇은"어떻게 든 프로그램 이름을 나타내는 제공을 제공합니다 . 더 가학적인 순간에 스와힐리어로 번역하고 대체 암호를 통해 실행 한 다음 역 바이트 순서로 저장하는 것을 고려할 것입니다 :-).
그러나 구현 정의 는 ISO 표준에서 특정 의미를 갖습니다. 구현시 작동 방식을 문서화해야합니다. 따라서 호출 제품군에 argv[0]
원하는 것을 수있는 UNIX조차도이를 exec
문서화해야합니다 (그리고 수행합니다).
에서 *nix
와 타입 시스템 exec*()
호출, argv[0]
에 어떤 발신자 풋 될 것에 argv0
자리 exec*()
전화.
쉘은 대부분의 프로그램 이름이라는 규칙을 사용하고 대부분의 다른 프로그램은 일반적으로 일반적으로 argv[0]
프로그램 이름입니다.
그러나 악성 Unix 프로그램은 원하는 것을 호출 exec()
하고 argv[0]
수 있으므로 C 표준이 말하는 것과 상관없이 시간을 100 % 믿을 수 없습니다.
C ++ 표준, 섹션 3.6.1에 따르면 :
argv [0]은 프로그램을 호출하는 데 사용되는 이름을 장르 NTMBS의 초기 문자에 대한 포인터 또는 ""입니다.
따라서 최소한의 표준에 의해 보장되지 않습니다.
이 페이지 는 다음을 설명합니다.
argv [0] 요소는 일반적으로 프로그램의 이름을 포함하지만, 이것은 의존 할 대상입니다. 어쨌든 프로그램이 자신의 이름을 알지 못하는 것은 드문 일입니다!
그러나 다른 페이지는 항상 실행 파일의 이름이라는 사실을 백업하는 것처럼 보입니다. 이것은 다음과 같이 사실.
argv [0]이 프로그램 자체의 경로와 이름임을 알 수 있습니다. 이를 통해 프로그램은 자신에 대한 정보를 사용할 수 있습니다. 또한 프로그램 인수 배열에 하나를 더 추가 할 때 명령 줄 인수를 추가 할 때 발생하는 오류는 argv [1]을 원할 때 argv [0]을 가져옵니다.
ISO-IEC 9899는 다음과 같이 사실.
5.1.2.2.1 프로그램 시작
의 값 이 0 보다 크면로 많음은 프로그램 이름을 나타냅니다. 호스트 환경에서 프로그램 이름을 사용할 수없는 경우 널 문자가됩니다. 의 값 이 1 보다 크면을 통해 가밍 은 프로그램 변수 를 나타냅니다 .
argc
argv[0]
argv[0][0]
argc
argv[1]
argv[argc-1]
나는 또한 사용했다 :
#if defined(_WIN32)
static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
{
return GetModuleFileNameA(NULL, pathName, (DWORD)pathNameCapacity);
}
#elif defined(__linux__) /* elif of: #if defined(_WIN32) */
#include <unistd.h>
static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
{
size_t pathNameSize = readlink("/proc/self/exe", pathName, pathNameCapacity - 1);
pathName[pathNameSize] = '\0';
return pathNameSize;
}
#elif defined(__APPLE__) /* elif of: #elif defined(__linux__) */
#include <mach-o/dyld.h>
static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
{
uint32_t pathNameSize = 0;
_NSGetExecutablePath(NULL, &pathNameSize);
if (pathNameSize > pathNameCapacity)
pathNameSize = pathNameCapacity;
if (!_NSGetExecutablePath(pathName, &pathNameSize))
{
char real[PATH_MAX];
if (realpath(pathName, real) != NULL)
{
pathNameSize = strlen(real);
strncpy(pathName, real, pathNameSize);
}
return pathNameSize;
}
return 0;
}
#else /* else of: #elif defined(__APPLE__) */
#error provide your own implementation
#endif /* end of: #if defined(_WIN32) */
그런 다음 디렉토리를 구문 분석하여 경로에서 실행 파일 이름을 추출해야합니다.
argv[0] !=
실행 가능한 이름 을을 응용 프로그램
많은 쉘이 확인하여 로그인 쉘인지 판별합니다
argv[0][0] == '-'
. 로그인 셸은 다른 속성을 가지고 있고 특히/etc/profile
.일반적으로 init 자체이거나
getty
선행을 추가합니다-
. https://unix.stackexchange.com/questions/299408/how-to-login-automatically-without-typing-the-root-username-or-password를 참조하십시오. -인-빌드 / 300152 # 300152다중 호출 바이너리, 아마도 가장 주목할만한 것은 Busybox 입니다. 이 심볼릭 링크 여러 이름은 예
/bin/sh
와/bin/ls
단일 exebutable에/bin/busybox
에서 사용하는 도구를 인식argv[0]
.이를 통해 여러 도구를 나타내는 하나의 작은 정적으로 연결된 실행 파일을 가질 수 있으며 기본적으로 모든 Linux 환경에서 작동합니다.
참조 : https://unix.stackexchange.com/questions/315812/why-does-argv-include-the-program-name/315817
실행 가능한 POSIX execve
예에서 argv[0] !=
실행 파일 이름
다른 사람들은 언급 exec
했지만 여기에 실행 가능한 예가 있습니다.
ac
#define _XOPEN_SOURCE 700
#include <unistd.h>
int main(void) {
char *argv[] = {"yada yada", NULL};
char *envp[] = {NULL};
execve("b.out", argv, envp);
}
기원전
#include <stdio.h>
int main(int argc, char **argv) {
puts(argv[0]);
}
그때:
gcc a.c -o a.out
gcc b.c -o b.out
./a.out
제공 :
yada yada
예, 다음과 argv[0]
같을 수도 있습니다.
- NULL : argv [0]은 언제 null을 가질 수 있습니까?
- 비어 있음 : argv [0]에 빈 문자열이 포함될 수 있습니까?
Ubuntu 16.10에서 테스트되었습니다.
거의 보편적 인 관습인지 표준인지는 잘 모르겠지만 어느 쪽이든 따라야합니다. 나는 그것이 유닉스와 유닉스 계열 시스템 밖에서 악용되는 것을 본 적이 없다. 유닉스 환경에서, 특히 예전에는 프로그램이 호출되는 이름에 따라 상당히 다른 동작을 할 수 있습니다.
편집 됨 : 다른 게시물에서 누군가가 특정 표준에서 나온 것으로 식별 한 것을 동시에 다른 게시물에서 볼 수 있지만,이 협약이 표준보다 오래 전부터 있다고 확신합니다.
Workbench로 Amiga 프로그램을 시작하면 argv [0]이 설정되지 않고 CLI로만 설정됩니다.
'IT' 카테고리의 다른 글
"세분화"및 "장면 라벨링"과 비교하여 "의미 적 세분화"는 무엇입니까? (0) | 2020.09.05 |
---|---|
Google Maps API 경고 : NoApiKeys (0) | 2020.09.05 |
Mercurial- 변경 설정에서 변경된 모든 파일? (0) | 2020.09.05 |
window.location.assign ()과 window.location.replace ()의 차이점 (0) | 2020.09.05 |
CSS 나는 div가 모든 것 위에 있기를 원합니다. (0) | 2020.09.05 |