代码之家  ›  专栏  ›  技术社区  ›  pythonic metaphor

什么会导致exec失败?接下来会发生什么?

  •  23
  • pythonic metaphor  · 技术社区  · 15 年前

    5 回复  |  直到 15 年前
        1
  •  21
  •   Community Mohan Dere    6 年前

    exec(3) man page

    execl() , execle() , execlp() , execvp() execvP() 函数可能会失败,并为库函数指定的任何错误设置errno execve(2) malloc(3)

    execv() 函数可能会失败,并为库函数指定的任何错误设置errno 执行(2) .

    然后从 execve(2) man page :

    错误

    Execve() 将失败并返回到调用进程,如果:

    • [E2BIG] sysctl(3) MIB变量 KERN_ARGMAX
    • [EACCES] -对路径前缀的组件的搜索权限被拒绝。
    • [答:]
    • [答:]
    • [答:] -新进程文件位于挂载了禁用执行的文件系统上( MNT_NOEXEC <sys/mount.h> ).
    • [EFAULT] -新进程文件的长度没有其标头中的大小值所指示的那么长。
    • [默认值]
    • [EIO]
    • [ELOOP] -翻译路径名时遇到太多符号链接。这被认为是表示循环符号链接。
    • [ENAMETOOLONG] -超出了路径名的组件 {NAME_MAX} 超过个字符或整个路径名 {PATH_MAX} 角色。
    • [ENOENT]
    • [ENOEXEC]
    • [ENOMEM] -新进程需要的虚拟内存比所施加的最大值所允许的要多( getrlimit(2) ).
    • [ENOTDIR]
    • [ETXTBSY] -新的进程文件是一个纯过程(共享文本)文件,它当前打开以供某些进程写入或读取。

    malloc() 简单得多,而且只使用 ENOMEM malloc(3) man page

    calloc() , malloc() , realloc() reallocf() ,和 valloc() 函数返回指向已分配内存的指针。如果出现错误,则返回 NULL errno 烯醇 .

        2
  •  39
  •   R.. GitHub STOP HELPING ICE    15 年前

    exec 失败通常是 执行 在子进程中执行,并且您希望在父进程中执行错误处理。但你不能 exit(errno) 执行

    我所知道的最好的解决方案是使用管道来传达 执行

    1. 分叉之前,在父进程中打开一个管道。
    2. 孩子叫exec。
    3. 如果子级成功执行,则父级读取eof(零长度读取) ,因为close-on-exec成功 关闭管道的写入端。或者,如果 执行 执行 .
    4. 父对象关闭管道的读取端。
        3
  •  8
  •   Jonathan Leffler    15 年前

    你下班后做什么 exec()

    问题的一个来源可能是您指定了一个简单的程序名而不是路径名;也许您可以用 execvp() ,或将命令转换为 sh -c 'what you originally specified' . 这些是否合理取决于应用。如果涉及到重大的安全问题,您可能不会再试一次。

    在可能的范围内,确保进程报告问题以便可以跟踪它是很重要的—将其消息写入日志文件或仅写入stderr(甚至可能是) syslog() ),这样那些必须找出哪里出了问题的人就可以得到更多的信息来帮助他们,而不是倒霉的最终用户的报告“我尝试了X,但它没有起作用”。至关重要的是,如果什么都不起作用,那么退出状态就不是0,因为这表示成功。即使这一点也可能被忽视——但你做了你能做的。

        4
  •  3
  •   user446568    15 年前

        5
  •  1
  •   Sam Watkins    14 年前

    (Shell除外,即如果用户输入了伪命令)

    如果exec失败,则表明:

    • 程序出现“故障”(缺少或损坏的组件、错误的路径名、错误的内存等),或
    • 严重的系统错误(内存不足、进程过多、磁盘故障等)

    对于任何严重的错误,通常的方法是在stderr上写错误消息,然后用失败代码退出。几乎所有的标准工具都能做到这一点。对于执行官:

    execl("bork", "bork", NULL);
    perror("failed: exec");
    exit(127);
    

    壳也会这样做(或多或少)。

    不要浪费太多时间去预测所有可能的错误情况。不要编写试图以最佳方式处理每个错误代码的代码。你只会膨胀代码,并引入许多新的错误。如果你的程序被破坏了,或者被滥用了,它就应该失败。如果你强迫它继续下去,更糟的麻烦会随之而来。

    例如,如果系统内存不足,并且正在进行彻底的交换,我们不想一遍又一遍地尝试运行进程;这只会使情况变得更糟。如果我们得到一个文件系统错误,我们不想继续在这个文件系统上运行;这可能会使损坏更严重。如果程序安装错误,或者有bug,或者内存损坏,我们希望在损坏的程序造成实际损坏(例如向客户端发送损坏的报告,破坏数据库,…)之前尽快停止。

    如果您正在制作一个交互式GUI程序,请尝试将其作为可重用命令行工具(如果出现问题,将退出)上的瘦包装器。程序中的每个函数都应该可以通过GUI、命令行和函数调用进行访问。写下你的函数。编写一些工具来为任何函数制作命令行和GUI包装器。也使用子进程。

    如果你在做一个真正关键的系统,比如核电站的控制器,或者海啸预报程序,那么你在读我愚蠢的建议做什么?关键系统不应完全依赖计算机或软件。需要有一个“手动超控”,有人来驱动它。特别是,不要试图在微软Windows上构建一个关键系统,就像在水下建造沙堡一样。