c-为什么posix_spawn()在popen()工作的地方失败?

我已成功使用popen()从我的C程序中运行命令.据我了解,它在幕后使用了fork()和exec()(或它们的变体).效果很好:

FILE *fd = popen("xterm", "r");
pclose(fd);

…将如预期的那样打开一个新的xterm窗口.

现在,我正在尝试使用posix_spawn()实现相同的功能,我理解这可能对资源更友好,尤其是如果我们不打算与新的子进程进行通信时,尤其如此:

/* p.we_wordv contains the argv, index 0 holds the actual command */
pid_t pid;
posix_spawnp(&pid, p.we_wordv[0], NULL, NULL, p.we_wordv, NULL);

…但这对于xterm作为命令,在父项的输出中产生以下内容:

xterm: Xt error: Can't open display:
xterm: DISPLAY is not set

尝试启动其他进程将产生其他错误消息,无提示地失败,或者在某些情况下(如ls)按预期工作.这使我很难真正看到一种模式.

您能否指出是什么导致第二种方法的行为不同于第一种?

最佳答案
消息未设置DISPLAY告诉您xterm找不到DISPLAY环境变量.所有图形输出程序均使用此环境变量连接到屏幕.

由于环境为空,因此未找到变量(这是posix_spawnp函数调用中的最后一个NULL).看来popen重用了当前进程的环境,所以它没有这个问题.

您可能想要传递仅包含所需内容的手动创建的环境,或者仅传递过程所具有的任何环境.后者更灵活(xterm将从您的进程继承各种配置设置,而这些配置设置则从您的shell继承它们),但可能存在安全风险.

要访问您的流程环境,请使用environ全局变量或更改您的main函数以接收其他参数:

int main(int argc, char *argv[], char *envp[])
{
    ...
    posix_spawnp(&pid, p.we_wordv[0], NULL, NULL, p.we_wordv, envp);
}

转载注明原文:c-为什么posix_spawn()在popen()工作的地方失败? - 代码日志