导航
  • 主页
  • 系统维护与使用
  • 应用程序开发
  • 内核源代码
  • 驱动程序开发
  • CPU和硬件区
  • UNIX文化
  • Solaris
  • Power Linux
  • 问答

先pipe() 然后fork() 子进程execl另一个可执行程序

老青蛙嘎嘎嘎 2009-12-31 09:46:16
如题,我调试的是 Beginning linux Programming(Third Edition)中第十三章的例子。pipe3 和pipe4 通信

pipe3源代码:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
int data_processed;
int file_pipes[2];
const char some_data[] = "123";
char buffer[BUFSIZ + 1];
pid_t fork_result;

memset(buffer, '\0', sizeof(buffer));

if(pipe(file_pipes) == 0)
{
fork_result = fork();
if(fork_result == (pid_t)-1)
{
fprintf(stderr, "Fork failure");
exit(EXIT_FAILURE);
}
if(fork_result == 0)
{
sprintf(buffer, "%d", file_pipes[0]);
(void)execl("pipe4", "pipe4", buffer, (char *)0);
exit(EXIT_FAILURE);
}
else
{
data_processed = write(file_pipes[1], some_data, strlen(some_data));
printf("%d - wrote %d bytes\n", getpid(), data_processed);
}
}
exit(EXIT_SUCCESS);
}

pipe4源代码:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
int data_processed;
int file_pipes[2];
const char some_data[] = "123";
char buffer[BUFSIZ + 1];
pid_t fork_result;

memset(buffer, '\0', sizeof(buffer));

if(pipe(file_pipes) == 0)
{
fork_result = fork();
if(fork_result == (pid_t)-1)
{
fprintf(stderr, "Fork failure");
exit(EXIT_FAILURE);
}
if(fork_result == 0)
{
sprintf(buffer, "%d", file_pipes[0]);
(void)execl("pipe4", "pipe4", buffer, (char *)0);
exit(EXIT_FAILURE);
}
else
{
data_processed = write(file_pipes[1], some_data, strlen(some_data));
printf("%d - wrote %d bytes\n", getpid(), data_processed);
}
}
exit(EXIT_SUCCESS);
}

我的疑问是:在pipe3中子进程启动了pipe4,把管道的读取端 文件描述符 传给了pipe4, pipe4怎么能认出 传递过来的文件描述符是管道的,而不是系统中其他进程的 文件描述符?
...全文
240 点赞 收藏 8
写回复
8 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
deep_pro 2009-12-31
[Quote=引用 7 楼 gutsyfarmer 的回复:]
至于pipe4怎么能认出 传递过来的文件描述符是管道的,而不是系统中其他进程的 文件描述符,应该研究下pipe()的源代码,现在姑且先记住吧!
[/Quote]
这个我倒不觉得有什么
管道也被抽象成文件了嘛
你可以在pipe4里读fd=3 写fd=4

这些exec细节我还真不知道
回复
至于pipe4怎么能认出 传递过来的文件描述符是管道的,而不是系统中其他进程的 文件描述符,应该研究下pipe()的源代码,现在姑且先记住吧!
回复
谢谢deep_pro的提醒,我查了一下书,感觉好像是下面这样,不对的话请指导!
执行 exec 函数族后,新程序对原程序已打开文件的处理与每个描述符的 close-on-exec 标志有关。若此标志设置,则在执行 exec 时关闭该描述符,否则该描述符仍打开。除非特地用 fcntl 设置了该标志,否则系统的默认操作是在执行 exec 后仍保持这种描述符打开。
回复
deep_pro 2009-12-31
我也很郁闷
pipe4可以
data_processed = read(3, buffer, BUFSIZ);

就是说exec创建pipe4时fd=3的文件描述符已经打开
这个应该是我们对exec函数族的理解不够深造成的吧
回复
不好意思啊,上面是pipe3的代码,下面是pipe4的代码:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
int data_processed;
char buffer[BUFSIZ + 1];
int file_descriptor;

memset(buffer, '\0', sizeof(buffer));
sscanf(argv[1], "%d", &file_descriptor);
data_processed = read(file_descriptor, buffer, BUFSIZ);

printf("%d - read %d bytes: %s\n", getpid(), data_processed, buffer);
exit(EXIT_SUCCESS);
}
回复
deep_pro 2009-12-31
lz的两个代码怎么一样啊
回复
关键是 子进程 执行了一个全新的进程,执行的新进程没有父子进程的资源,如果有的话也不用传 pipe读端的 文件描述符了
回复
deep_pro 2009-12-31
他们是父子进程,子进程有fork前的父进程所有资源的一个拷贝。
回复
发动态
发帖子
Linux/Unix社区
创建于2007-08-27

2.0w+

社区成员

Linux/Unix社区 应用程序开发区
申请成为版主
社区公告
暂无公告