【问题标题】:communicate with an execv()'ed program via pipe doesn't work通过管道与 execv()'ed 程序通信不起作用
【发布时间】:2012-11-08 07:22:18
【问题描述】:

我尝试编写一个套接字来加载程序并将套接字 io 重定向到这些程序。听起来很像inetd,但据我所知,inetd 会在请求其端口时加载程序。我想让它永久加载。

到目前为止一切顺利。编写套接字服务器并不是那么棘手,但我没有让其余的工作。 我基本上想打开一个管道(),dup2()它到stdin和stdout和execv()我的程序。

问题是,我被调用的程序没有得到任何输入。我会尝试用一个测试程序来展示它。有人可以告诉我,怎么了?

int create_program_fork(int *ios, char const *program) { 
// create pipes to program 
if (pipe(ios) != 0) { 
    return -1; 
} 

// fork to new process 
int f = fork(); 
if (f < 0) { 
    // fork didn't work 
    close(ios[0]); 
    close(ios[1]); 
    return(-1); 
} 
if (f > 0) { 
    // master hasn't much to do here 
    return f; 
} 
// *** Child Process 
// close std** file descriptors 
printf ("executing program"); 
close(STDIN_FILENO); 
close(STDOUT_FILENO); 
// duplicate pipes as std** 
dup2(ios[0], STDIN_FILENO); 
dup2(ios[1], STDOUT_FILENO); 
// close pipes 
close(ios[0]); 
close(ios[1]); 
// call program 
return execvp(program, NULL ); 
} 

int main(int argc, char *argv[]) { 
int ios[2]; 

// call program 
int pid = create_program_fork(ios, "/bin/bash"); 
if (0 != pid){ 
    exit(EXIT_FAILURE); 
} 

char const exit_order[] = "exit\0"; 
char const order[] = ">/tmp/test.txt\0"; 
// do something 
write(ios[1], order, strlen(order)); 
// bash should stop then.. 
write(ios[1], exit_order, strlen(exit_order));   
return 0; 
}

【问题讨论】:

  • 我只是想看看结果。 >/tmp/test.txt 应该在 /tmp 中创建了一个文件,但它没有。

标签: c pipe stdout stdin execv


【解决方案1】:

我看到两个可能的问题来源:

1) 管道的写部分被重定向到孩子的标准输出,所以新进程的输出 被送回输入。我建议只在子端复制管道的读取部分。如果你想拦截孩子的输出,你需要另一个通道(即一个新的管道,或者干脆让父母和孩子共享同一个标准输出)。

2) 您发送的字符串似乎包含面向行的命令。子进程可能期望字符串末尾有换行符。这是一个非常常见的问题来源。我建议检查孩子阅读其输入的方式。字符串末尾的“\n”可能会有所帮助(顺便说一下,没有必要在 C 字符串的末尾显式添加“\0”,因为编译器会为你做这件事。无论如何,strlen 不会计算“\0”)。

【讨论】:

  • 新管道是什么意思?
  • 如果你想捕获孩子的输出,你必须将它重定向到某个地方,就像你重定向输入一样。经常使用的解决方案是创建第二个管道,其写入部分连接到子级的输出。当然,父级必须从第二个管道读取才能接收子级的输出。但这取决于您的特定应用程序。最简单的方法是什么都不做,所以子进程继承父进程的输出。无论如何,在您的代码中,管道写入部分的子输出重定向非常奇怪,因为进程最终会将其输出发送给自己。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-10
  • 2021-12-16
  • 2011-12-22
  • 2010-09-26
  • 1970-01-01
  • 2013-04-01
相关资源
最近更新 更多