简体   繁体   English

fork / exec:尝试重定向stdin / stdout时子退出

[英]fork/exec: child exits when trying to redirect stdin/stdout

I'm trying to control a shell-like process from my program using fork/exec, using pipes to write commands to the process and read its output. 我正在尝试使用fork / exec从我的程序中控制类似shell的进程,使用管道将命令写入该进程并读取其输出。 If I create the process without any redirecting, it runs without exiting, as expected - I can see both the parent and the child in the ps output. 如果我创建该进程而没有任何重定向,则它会按预期运行而不会退出-我可以在ps输出中看到父级和子级。 However, once I add the redirect code in, the child seems to exit immediately (it shows as "defunct" in ps). 但是,一旦我添加了重定向代码,该子级似乎立即退出(在ps中显示为“ defunct”)。 I'm not sure how to determine why the child process is exiting (I don't see any output from it), so I'm struggling to diagnose the problem. 我不确定如何确定子进程为何退出(我看不到该进程的任何输出),所以我在努力诊断问题。

My code looks something like this: 我的代码如下所示:

int in[2], out[2];
FILE *in_fp, *out_fp;

pipe(in);
pipe(out);

if (fork()) {
    close(in[0]);
    close(out[1]);
    in_fp = fdopen(in[1], "w");
    out_fp = fdopen(out[0], "r");

    // Here I'll use in_fp and out_fp to communicate with the child.
} else {
    dup2(in[0], STDIN_FILENO);
    dup2(out[1], STDOUT_FILENO);
    close(in[0]);
    close(in[1]);
    close(out[0]);
    close(out[1]);

    execlp("child_process", NULL);
}

Does anyone know why this might not be working, or suggest how I can get more info about why the child process exits? 有谁知道为什么这可能行不通,或者建议我如何获得有关子进程为何退出的更多信息?

edit: So strace reveals the child process is crashing with a SIGSEGV, and looks like it's in Py_SetProgramName - though can't work out why yet (don't have access to the child's symbols). 编辑:因此strace揭示了子进程正在使用SIGSEGV崩溃,并且看起来像在Py_SetProgramName中-尽管尚不能弄清原因(无法访问子代的符号)。

Probably the problem is in the call to execlp() . 问题可能出在对execlp()的调用中。

Although technically the list of arguments may be empty, it is standard practice to add always at least one argument, that will be argv[0] in main() , with the actual name used to invoke the program. 尽管从技术上讲,参数列表可能为空,但通常的做法是始终至少添加一个参数,该参数在main()argv[0] ,其实际名称用于调用程序。 Likely the python program uses this arg0 as argument to Py_SetProgramName() without checking for NULL . 可能是python程序使用此arg0作为Py_SetProgramName()参数,而不检查NULL

So write instead: 所以写:

execlp("child_process", "child_process", (char*)NULL);

Also note that, citing from man execlp : 另请注意,引用自man execlp

The list of arguments must be terminated by a null pointer, and, since these are variadic functions, this pointer must be cast (char *)NULL 参数列表必须以空指针终止,并且由于它们是可变参数函数,因此必须将该指针强制转换(char *)NULL

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM