fork-exec后无法打开文件

时间:2013-07-29 01:18:55

标签: c++ file-io exec fork

我正在用fork-exec模式编写一些代码,而子进程用于打开/ tmp目录(append-create模式)中的文件以将其输出写入。 (该文件不是提前存在,而是在打开时创建的,或者至少它应该是......)但是,我发现孩子在exec之后无法打开任何文件。它可以打开/创建一个文件并在fork之后和exec之前写入它,但是在exec之后我发现文件没有被创建。此外,如果我运行程序我在命令行上执行(使用相同的参数),它会创建文件并写入它就好了。只有从exec开始它才会出现这个问题。我真的不知道如何开始思考这个问题...如果有人建议在哪里寻找线索,我真的很感激!

这是一个粗略的例子 - 注意这不是运行的实际代码:) 子:

#define MSG "Opened file: "
int main (usual stuff) {
    const char* szTemp = "/tmp/helloworld";
    FILE* temp = fopen(szTemp, "a");
    fwrite(MSG, sizeof(char), strlen(MSG), temp);
    fwrite(szTemp, sizeof(char), strlen(szTemp), temp);
    fwrite("\n", sizeof(char), 1, temp);
    fclose(temp);
    // at this point, I see the file with the normal content when Child is run
    // from the command line, but the file is not created if Child is created
    // by a call to exec
}

父:

int main(usual stuff) {
    pid_t pid = fork();
    if (0 == pid) {
        // fopen/fwrite works fine if I do it here!
        exec(child-process);
    }
    // parent continues...
}

1 个答案:

答案 0 :(得分:0)

好的,我明白了!这就是发生的事情:在exec被调用之前触及文件的代码显然已经运行并且做了它应该做的事情。主要启动后立即触摸文件的代码没有触及文件,因为它从未运行过。这个过程在exec和main之间死了!

有很多方法可以实现,但在我的情况下,这是因为它试图加载共享对象(.so)文件(动态链接库的Linux风格),但路径不在LD_LIBRARY_PATH中所以它失败了。 (从命令行开始,一切正常,因为我的LD_LIBRARY_PATH确实包含了正确的目录,但我从fork开始的进程无权访问该环境...)解决方案是简单地使用exec的evnironment参数传入LD_LIBRARY_PATH的正确值,然后子进程可以找到.so文件并正确启动。

现在,这就是为什么在这种情况下很难检测到...通常如果一个进程在启动时找不到必要的.so它会给你一条消息(在stderr,我相信)让你确切地知道它找不到哪个库。我的麻烦是父进程是一个守护进程,所以我关闭了stdin,stdout和stderr。当我fork时,子进程继承了打开的文件描述符,但由于标准流已关闭,因此它没有任何地方可以发送它的输出。一旦我添加了代码以使子进程发送stdout& stderr到一个文件(这是在fork和exec之间完成的),我能够在输出文件中看到错误消息。

我在这里有点幸运,因为我正在为stdout / stderr添加输出(主要是)无关的原因......