我想为我的C ++程序找到安装了.pdf浏览器的软件。我希望使用popen,但是即使这段代码也会导致返回nun-NULL
FILE *fp;
fp = popen("abracadabraxx ", "r");
如果没有安装该应用程序,我希望无法进行分叉。我会误会什么吗?
答案 0 :(得分:6)
popen
打开管道。并且:
如果fork(2)或pipe(2)调用失败,或者该函数无法分配内存,则返回NULL。
这两个条件均与打开管道的过程无关。它们是关于管道本身的。
要确定进程是否成功,您需要进入pclose
阶段,并且:
pclose():成功后,返回命令的退出状态;如果wait4(2)返回错误,或检测到其他错误,则返回-1。
您正在尝试捕获the event that the shell returns an exit code of 127,可以通过WEXITSTATUS
获取。
示例:
#include <cstdio>
#include <iostream>
#include <sys/wait.h>
int main()
{
FILE* fd = popen("nonexistingfoobar", "r");
const int res = pclose(fd);
printf("%d\n", WEXITSTATUS(res));
}
始终阅读the documentation!
答案 1 :(得分:1)
如果没有安装该应用程序,我希望无法进行分叉
As per documentation,popen
启动外壳程序(在POSIX系统上使用/bin/sh -c
),并返回连接到外壳程序输出(或输入,取决于第二个参数)的文件描述符。该命令的有效性与popen
“本身”的成功与否无关,因此您不会在输出中获得NULL
(这是较低级别的失败(例如不可能)的预期结果)派生,创建文件描述符或exec
shell本身,除非在资源匮乏的情况下,否则所有“不应该发生的事情”。
您将只获得标准外壳程序输出的shell会发出的任何消息(可能不会,因为它将出现在标准错误中);顺便说一句,这就是为什么popen
通常不是一个好主意的原因之一,如果您需要对出问题的地方进行适当的诊断。
您可以 做的是检查pclose
的返回码,该返回码将为您提供 shell 退出码,您可以使用该退出码找出发生问题的详细信息(如果有)。
ShellExecute
API,macOS上的open
实用程序和大多数 Linux安装中的xdg-open
实用程序 1 < / sup>。
对于获取用于启动文件的可执行文件,这是一种更为复杂的方法。我不知道macOS,但在Windows上,文件可能与比“普通”可执行文件(可能是通过命令行)更复杂的东西相关联-曾经有DDE命令,一些自动安装的新MSI讨厌按需填充和其他“魔术”外壳填充;我怀疑即使在Linux上,也会对DBus激活应用程序之类的东西提供一些中断的支持;因此,通常没有“关联可执行文件”之类的东西,只需要求系统打开文件并避免这种麻烦即可。
xdg-open
通常是一个安全的赌注(尽管我也看到它失败了)。不要沿着Firefox自己尝试做这些事情的道路前进,否则您也会因启动错误的应用程序而存在10年的错误,并会定期出现。