我正在学习linux编程并且遇到了exec函数,它非常有用。但问题是exec函数参数非常混乱,我无法掌握哪个参数是出于什么目的。在下面的代码execl()
函数是从通过fork()
创建的子函数调用的,是什么NULL
中最后一个参数(execl()
)的目的是什么?
execl("/bin/ls","ls","-l",NULL);
如果有人可以解释NULL
论证的目的和其他论点的目的以及exec()
家庭功能论证的目的,那对我来说将是一个很大的帮助!
答案 0 :(得分:11)
创建未定义的行为。这不是对execl
的合法要求。一个
正确的电话可能是:
execl( "/bin/ls", "ls", "-l", (char*)0 );
最后一个参数必须为(char*)0
,或者您有未定义的行为。
第一个参数是可执行文件的路径。下列
参数出现在已执行程序的argv
中。这些清单
参数由(char*)0
终止;这就是被调用的函数
知道最后一个参数已经达到。在上面的例子中,
例如,"/bin/ls"
处的可执行文件将替换您的代码;在
其main
,argc
等于2,argv[0]
等于"ls"
,
和argv[1]
相等"-l"
。
在此功能之后,您应立即进行错误处理
码。 (execl
总是在返回时返回-1,因此您不需要
测试一下。并且只有在出现某种错误时它才会返回。)
答案 1 :(得分:4)
exec
函数是可变参数:它们采用可变数量的参数,以便您可以向命令传递可变数量的参数。这些函数需要使用NULL
作为标记来标记参数列表的结尾。
在可变函数中,循环将迭代可变数量的参数。这些循环需要终止条件。在某些情况下,例如printf
,可以从另一个参数推断出实际的参数数量。在其他功能中,NULL
用于标记列表的末尾。
另一种选择是为参数个数添加一个额外的函数参数,但这会使代码变得更脆弱,需要程序员管理一个额外的参数,而不是简单地总是使用最后一个NULL
。
您还会看到(char *) 0
用作标记:
execl("/bin/ls", "ls", "-l", (char *) 0);
答案 2 :(得分:1)
在/usr/include/libio.h
中,由于gcc 2.8(很久以前)NULL
被定义为 null(是为内置词保留的),因此NULL
之前} (void *)0
在(char *)0
情况下与varargs
无法区分,因为未传递类型,例外情况是__cplusplus
定义在哪种情况下NULL
定义为0.
特别是如果你有一个64位架构,安全的做法是明确使用(void *)0
,它被定义为与任何指针兼容,而不依赖于可能发生的任何狡猾的#defines
在标准库中。
答案 3 :(得分:0)
(char *) 0
的目的用于终止参数。如果缺少此行为,可能会导致未定义的行为。 手册页将 execl 签名定义为:
int execl(const char *path, const char *arg, ...);
path :要调用的程序的位置,即要调用的程序的位置。
arg ,... *:可以认为是arg0,arg1,...,argn。
在您的情况下,execl( "/bin/ls", "ls", "-l", (char*)0 );
是正确的函数调用。
“ bin / ls ”要调用的程序
“ ls ”程序名称
“ -l </ em>”是该程序的参数,称为