popen()
到另一个以及dup()
stdout process_test.c
:
#include <stdio.h>
#include <unistd.h>
int main() {
int out;
out = dup(STDOUT_FILENO);
// close(out);
popen("sleep 10\0", "r");
}
使用gcc process_test.c
进行编译,使用以下命令运行:
./a.out
- &gt;通常退出ruby -e 'system("./a.out");'
- &gt;通常退出php -r passthry("./a.out");
- &gt;挂起ssh remotehost ./a.out
- &gt;挂起dup
stdout或关闭dup时,它不会挂起这是我能找到的最短可重现的代码,它向我展示了一种我想要更好理解的行为。
使用fork / pcntl / etc从多个PHP应用程序/框架中提取它需要花费数小时。修好他们的关系,即我没有写下这个或者说这个;但很显然,由于我将所有东西分开,所以它的整体意识都会丢失。
答案 0 :(得分:0)
因为当通过ssh调用程序时,stdoud上的dup是由ssh生成的,所以当ssh尝试结束时它不能,因为stdout还有另一个通道已打开。
我试着给你一个更好的答案: 如果我没记错的话,stdout就是1号频道。制作dup我们还有指向stdout的新频道3。 当ssh尝试关闭通道2 togheter到通道0和2(stdinput和stderr)时,ssh无法自行关闭,因为有另一个资源占用了通道3或更好的stdout。
我希望这一点足够明确 加埃塔诺
如果我按原样运行你的演示,我得到errno = 15,或者它可以是16,如本答案结尾所述。 但是,如果我以不同的方式运行它:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
int main() {
int out;
int status;
out = dup(STDOUT_FILENO);
// close(out);
FILE *fp = popen("sleep 10\0", "r");
status = pclose(fp);
if (status == -1) {
printf("pclose error: %d", errno);
}
close(out);
}
我再也没有得到错误。 要检查bash下的错误,我使用:echo $?
这意味着您必须在退出c程序之前重新发布所有已分配的资源。
我希望这一切。
最好的反馈 加埃塔诺
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */