exec* 的 argv 可以在多个地方包含值 0 吗?
Can exec*'s argv contain a value of 0 in multiple places?
我读到 exec
创建新进程后,
argv is an array of argument strings, with argv[argc] == 0
如果数组 argv
中的其他值之一恰好为 0,会发生什么情况?子进程运行时会不会计算出参数个数(argc
)不正确?
我在 AMD64 的 ABI (https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf) 的第 34 页上读到了这个。
execve
系统调用(被所有 exec*
函数使用)有一个形式为 char *const argv[]
的参数。内核通过迭代提供的 argv
作为 follows:
来计算 argc
static int count(struct user_arg_ptr argv, int max)
{
int i = 0;
if (argv.ptr.native != NULL) {
for (;;) {
const char __user *p = get_user_arg_ptr(argv, i);
if (!p)
break;
if (IS_ERR(p))
return -EFAULT;
if (i >= max)
return -E2BIG;
++i;
if (fatal_signal_pending(current))
return -ERESTARTNOHAND;
cond_resched();
}
}
return i;
}
函数get_user_arg_ptr
本质上是计算argv
数组的索引和returns存储在该索引处的指针。循环在四种情况下中断,其中两种与您的问题相关:
- 在 argv 数组中看到的第一个
NULL
。如果在 argv
中的第一个 NULL
之后还有其他指针,它们将被忽略。有多个 NULL
闻起来像是构建 argv
. 的程序中的错误
- 当指针数大于等于
MAX_ARG_STRINGS
时,即defined为0x7FFFFFFF
。在这种情况下,系统调用失败。
当get_user_arg_ptr
returns.
时返回的i
的值赋值给argc
argv
中终止 NULL
的另一种情况是当应用程序本身使用 argv
时,如下所示:
for(char **p = argv; *p != NULL; ++p)
{
// ...
}
它是 Linux ABI 的一部分,argv
以 NULL
终止,因此此类代码在所有 Linux 实现中都是合法且可移植的。顺便说一句,此代码在 Windows 上也是合法的。因此,argc
仅供参考。
此外,C 和 C++ 标准分别在 5.1.2.2.1 和 3.6.1 中声明,如果 argc
大于零,则 argv[0]
中的所有值通过argv[argc-1]
应是 non-null 指向 null-terminated 字符串的指针。另外 argv[argc]
必须为 null,并且 argc
是 non-negative。另请参阅 this 答案。
我读到 exec
创建新进程后,
argv is an array of argument strings, with
argv[argc] == 0
如果数组 argv
中的其他值之一恰好为 0,会发生什么情况?子进程运行时会不会计算出参数个数(argc
)不正确?
我在 AMD64 的 ABI (https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf) 的第 34 页上读到了这个。
execve
系统调用(被所有 exec*
函数使用)有一个形式为 char *const argv[]
的参数。内核通过迭代提供的 argv
作为 follows:
argc
static int count(struct user_arg_ptr argv, int max)
{
int i = 0;
if (argv.ptr.native != NULL) {
for (;;) {
const char __user *p = get_user_arg_ptr(argv, i);
if (!p)
break;
if (IS_ERR(p))
return -EFAULT;
if (i >= max)
return -E2BIG;
++i;
if (fatal_signal_pending(current))
return -ERESTARTNOHAND;
cond_resched();
}
}
return i;
}
函数get_user_arg_ptr
本质上是计算argv
数组的索引和returns存储在该索引处的指针。循环在四种情况下中断,其中两种与您的问题相关:
- 在 argv 数组中看到的第一个
NULL
。如果在argv
中的第一个NULL
之后还有其他指针,它们将被忽略。有多个NULL
闻起来像是构建argv
. 的程序中的错误
- 当指针数大于等于
MAX_ARG_STRINGS
时,即defined为0x7FFFFFFF
。在这种情况下,系统调用失败。
当get_user_arg_ptr
returns.
i
的值赋值给argc
argv
中终止 NULL
的另一种情况是当应用程序本身使用 argv
时,如下所示:
for(char **p = argv; *p != NULL; ++p)
{
// ...
}
它是 Linux ABI 的一部分,argv
以 NULL
终止,因此此类代码在所有 Linux 实现中都是合法且可移植的。顺便说一句,此代码在 Windows 上也是合法的。因此,argc
仅供参考。
此外,C 和 C++ 标准分别在 5.1.2.2.1 和 3.6.1 中声明,如果 argc
大于零,则 argv[0]
中的所有值通过argv[argc-1]
应是 non-null 指向 null-terminated 字符串的指针。另外 argv[argc]
必须为 null,并且 argc
是 non-negative。另请参阅 this 答案。