- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这是execv
的原型(prototype):
int execv(const char *path, char *const argv[]);
我可以传递一个 const char
指针数组作为第二个参数吗?
当未设置 USE_CAST
时,此示例程序会发出警告:
#include <unistd.h>
int main(int argc, char *argv[])
{
if (argc > 0) {
const char *exe_name = "/bin/echo", *message = "You ran";
const char *exe_args[] = { exe_name, message, argv[0], NULL };
#ifdef USE_CAST
execv("/bin/echo", (char **) exe_args);
#else
execv("/bin/echo", exe_args);
#endif
}
return 0;
}
编译时,如果我不使用强制转换,gcc 会提示“从不兼容的指针类型传递‘execv’的参数 2”。
来自POSIX documentation对于 execv
(基本原理部分的一半),看起来第二个参数是一个 char *const
数组,只是为了向后兼容:
The statement about
argv[]
andenvp[]
being constants is included to make explicit to future writers of language bindings that these objects are completely constant. ... It is unfortunate that the fourth column cannot be used...
其中“第四列”指的是 const char* const[]
。
(char **)
在这里使用是否安全?我应该创建一个 char *
数组并将其传递给 execv
吗?
最佳答案
Can I pass an array of const char pointers as the second argument?
是的,你已经知道你可以施法来做到这一点。
From the POSIX documentation for execv (halfway through the Rationale section), it looks like the second argument is a char *const array only for backwards compatibility:
我不会用那些术语来表达它,但是,是的,所选签名存在兼容性方面的问题。您引用的部分解释说,C 没有完全令人满意的方式来表达 POSIX 要求 execv()
为参数提供的 const
程度。 POSIX 保证该函数不会更改 argv
中的指针或它们指向的字符串。
在这种情况下,我认为按照您的建议转换 argv
指针并非不合理,尽管我会在我的代码中留下评论,解释为什么这样做是安全的。
另一方面,您应该考虑将 const
简单地从您的数组声明中删除:
char *exe_name = "echo", *message = "You ran";
char *exe_args[] = { exe_name, message, argv[0], NULL };
或者,在您的简单示例中,即使这样也可以:
char *exe_args[] = { "echo", message, argv[0], "You ran", NULL };
C 字符串文字对应于 char
类型的数组,而不是 const char
,所以就 C 而言,这是完全合法的,即使实际上试图修改这些字符串的内容可能会失败。
另一方面,现代 C 有数组文字,所以你甚至可以这样做:
execv("/bin/echo", (char *[]) { "echo", "You ran ", argv[0], NULL });
在最后一种情况下,您甚至没有强制转换(类似于一个的东西只是数组文字语法的一部分)。
关于我可以将 const char* 数组传递给 execv 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36925388/
该程序在嵌入式 Linux 上执行(内核版本:3.4.0)。在调用execve()之前,还调用了setgid()和setuid()切换到另一个用户(tstuser).用户存在,必要的条目在 /etc/
我使用 execv 和参数:$PATH 调用 echo,输出是 $PATH,而不是 $PATH 环境变量的实际值,这是我在 bash 中执行相同操作时得到的值。 为什么会发生这种情况?我传递了所有正确
我在使用此 execve 命令时遇到问题。我可以在我的程序中使用它来运行大多数其他命令,但如果我尝试执行 man ls 之类的操作,我会收到此错误。 man: can't execute pager:
在 C 程序中,main 函数通过查看 argc 知道在 argv 中传递了多少参数。我似乎不清楚 syscall execve 如何知道传递给它的参数数量。有人可以帮助解释 execve 如何处理参
我是新手,所以我可能对表达不准确。我需要用汇编程序在 C 中进行系统调用“execve”。我不使用任何库。不起作用的部分是 char *nul=(char *)0; char *argv[] = {
我的教授编写了一个程序,它使用 execve() 打印工作目录 (pwd),但我不明白其中的参数。 pid_t pid = fork(); if(pid int main(int argc, cha
我有一个名为“test”的程序,它执行另一个名为“hello”的程序。收到所需程序的名称后,我的程序似乎等待更多输入才能显示“hello”程序代码。示例代码片段 #include #include
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 Improve th
我在使用 C 程序时遇到了一些神秘的情况,该程序在我的电脑上运行良好,但当我在我正在使用的服务器上编译它时却失败了。基本上execve执行失败。原来的程序不太大,所以我开始削减一些部分,以尝试了解问题
我正在尝试在 Linux 计算机上测试绝对路径以查找程序所在的位置,以便我可以使用特定参数运行它。问题是,当我找到它时,我不断向正确的路径添加更多字符串,并通过释放动态分配的内存来导致内存泄漏。堆栈转
我必须执行一个路径未知的命令。我可以到达环境路径,但如何使用它们?例如,如果有 5 个不同的路径,我应该在 execv 中尝试哪一个? /usr/lib/lightdm/lightdm:/usr/lo
我对此困惑了一段时间,现在我需要一些帮助。我正在尝试创建一个循环,该循环将 fork 子进程并通过 execve() 调用“echo hello”。 #include #include #inc
我的程序中有这个: execv (programname, (char **)argv); 我不确定命令是否真的被正确执行了。我怎样才能知道?这是在后台运行吗? 最佳答案 我强烈建议你买一本与你正在
我必须制作一个自定义 shell 作为学校项目,但我遇到了困难: int exec_shell(char **argv) // { if (execve(argv[0], (char **)a
我试图找到我当前的 PATH 以在我的 execv() 命令中使用它,但我仍然无法弄清楚如何找到任何提示的路径? 最佳答案 获取当前PATH variable从您的环境中(参见 environ(7)
了解 Linux 内核说 execve() 调用每个 linux_binfmt 对象的 load_binary(),并且 load_binary() Invokes the start_thread(
我们有一个从 inittab 启动的 stub ,execv 是我们的进程。 (ARM Linux 内核 2.6.25) 测试进程时,只有从 inittab 启动并执行时才会失败。如果在命令行上启动,
程序应该做什么的例子: ./executable ls -l 应该做同样的事 ls -l 所以基本上它是一个无用的 shell 命令解释器。 我创建了一个包含/bin/commandname 的字符串
我想编写一个程序来执行 Linux ls 命令。我真的只想输入 ls 而不是 /bin/ls,所以我想使用 execve (execvp 不是一个选项)。 我试过: char *env[] = { "
我有一项大学作业,我需要从管道中读取 bash 命令并执行该命令。我正在考虑使用 execv*,因为我可以通过以空格作为分隔符来创建缓冲区。问题是我不能使用 STL 库,而且我不知道应该如何创建这个缓
我是一名优秀的程序员,十分优秀!