c中的Exec函数在应该返回时没有返回-1
我正在使用execv函数运行一个名为code.x的程序。 code.x有一部分通过断言保证其失败。 我运行execl的代码是:c中的Exec函数在应该返回时没有返回-1,c,fork,exec,C,Fork,Exec,我正在使用execv函数运行一个名为code.x的程序。 code.x有一部分通过断言保证其失败。 我运行execl的代码是: #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> #include <errno.h> #include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
int main()
{
pid_t pid;
char *args[] = { "./code.x",NULL };
pid = fork();
if (pid > 0) {
wait(NULL);
printf("%s\n", strerror(errno));
printf("done\n");
}
else if (pid == 0) {
printf("%s\n", strerror(errno));
execv(args[0], args);
printf("should fail");
}
else {
printf("forkfail");
}
return 1;
}
从不打印“应失败”,WEXITSTATUS(状态)显示退出状态为0。
execv
成功完成其工作。进程/code.x
已执行,然后由于断言而退出
exec函数族不关心进程的返回值。一旦进程启动,调用进程就会有效地终止并消失
只有由于某种原因无法启动进程时,Exec才会返回。具体而言,只有这些错误(取自手册页)才会导致exec返回并将errno
设置为以下值之一:
环境(envp)和参数列表(argv)中的总字节数太大E2BIG
对文件名路径前缀或脚本解释器名称的组件的搜索权限被拒绝。(另见路径_决议(7))EACCES
文件或脚本解释器不是常规文件EACCES
文件、脚本或ELF解释器的执行权限被拒绝EACCES
文件系统在noexec上装载EACCES
(从Linux 3.1开始) 在使用set*UID()调用之一更改了其真实UID后,调用方过去和现在都高于其RLIMIT_NPROC资源限制(请参阅 setrlimit(2))。有关此错误的更详细解释,请参见注释EAGAIN
filename或向量argv或envp中的一个指针指向可访问地址空间之外EFAULT
一个ELF可执行文件有多个PT_INTERP段(即,试图命名多个解释器)EINVAL
发生I/O错误EIO
ELF解释器是一个目录EISDIR
ELF解释器的格式不可识别elibad
解析脚本或ELF解释器的文件名或名称时遇到太多符号链接ELOOP
递归脚本解释过程中达到了最大递归限制(请参见上文的“解释器脚本”)。在Linux3.8之前 此案例产生的错误为ENOEXECELOOP
已达到每个进程对打开的文件描述符数量的限制EMFILE
文件名太长enametolong
已达到系统范围内打开文件总数的限制ENFILE
文件名、脚本或ELF解释器不存在,或者找不到文件或解释器所需的共享库enoint
可执行文件的格式不可识别、架构错误或存在其他格式错误,这意味着无法执行ENOEXEC
内核内存不足ENOMEM
文件名或脚本或ELF解释器的路径前缀的组件不是目录ENOTDIR
文件系统是以nosuid装载的,用户不是超级用户,并且文件设置了set user ID或set group ID位EPERM
正在跟踪进程,用户不是超级用户,并且文件已设置了设置用户ID或设置组ID位EPERM
A“能力哑”应用程序将无法获得可执行文件授予的全部允许能力。见能力(7)EPERM
指定的可执行文件已被一个或多个进程打开以供写入ETXTBSY
如果您正在调用的程序
/code.x
中发生断言失败,这已经远远超过了execv
可能失败的点;此时,执行execv
的原始程序状态不再存在,因为它已被替换。父进程将通过wait
-系列函数看到它退出,并且可以检查wait
-系列函数报告的状态,以确定它退出的原因。exec*
函数在程序开始运行时成功。你的程序确实开始运行了
断言失败导致程序中止,并发出信号退出。Linux解释说:
WEXITSTATUS(wstatus)
返回子级的退出状态。这包括子级在调用exit(3)
或\u exit(2)
或as时指定的状态参数的最低有效8位
main()
中返回语句的参数只有当WIFEXITED
返回true时,才应使用此宏。
如果您没有检查WIFEXITED(status)
是否为真,则WEXITSTATUS(status)
为垃圾
相反,请检查
WIFSIGNALED(status)
,如果为true,则获取信号-WTERMSIG(status)
,该信号应等于SIGABRT
Exec函数系列将现有进程映像替换为新进程映像。这就是为什么在生成另一个进程之前需要fork,因为当前运行的进程是完全可重用的
Success
code.x: code.c:15: main: Assertion '0 == 1' failed.
Success
done
printf("should fail");