通过管道与execv()'ed程序通信不起作用

时间:2012-11-08 07:22:19

标签: c pipe stdout stdin execv

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

到目前为止一切顺利。编写套接字服务器并不是那么棘手,但我没有让其他工作。 我基本上想打开一个pipe(),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; 
}

1 个答案:

答案 0 :(得分:1)

我看到两个可能的麻烦来源:

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

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