可以popen()完成建立双向管道像管()+ fork()的? [英] Can popen() make bidirectional pipes like pipe() + fork()?
问题描述
我在实现C ++模拟文件系统(带主要是C)上的管道。它需要在主机shell中运行命令,但模拟的文件系统上执行的管道本身。
我可以用管道实现这一目标()
,叉()
和系统()
系统调用,但我preFER使用的popen()
(它处理创建一个管道,派生进程,并传递到shell命令)。这未必是可能的,因为(我想)我需要能够从管道,在子处理结束阅读的父进程写,写输出从子后面,最后读取从父该输出。该手册页的popen()
我的系统上说,一个双向管是可能的,但我的code需要与旧版本的系统上运行,只支持单向管道。
通过上面的单独调用,我可以打开/关闭管道实现这一目标。这有可能与的popen()
?
有关一个简单的例子,运行的ls -l |用grep .TXT | grep的CMDS
我需要:
- 打开一个管道和进程来运行
的ls -l </ code>主机上;读它的输出回
- 管的输出
的ls -l </ code>回到我的模拟器
- 开启管道和工艺对
的ls -l </ code>的管道输出的主机上运行
的grep .TXT
- 管这回模拟器的输出(困在这里)
- 打开一个管道和进程来运行
的grep CMDS
上的管道输出的主机上的grep .TXT
- 管这回模拟器的输出和打印
男人的popen
从Mac OS X:
的
的popen()
函数'打开'一
通过创建一个双向的过程
管道,分叉,并调用外壳。
由previous的popen打开的任何流()
在父进程调用关闭
在新的子进程。
从历史上看,的popen()
开始实施
与单向管;因此,
许多实施的popen()
只
允许模式参数指定
读取或写入,而不是两个。因为
的popen()
现在使用的是实施
双向管,mode参数
可以要求双向数据流。
mode参数是一个指针
null结尾的字符串必须是
R的阅读,'W'的文笔,或者
R +用于读取和写入。
块引用>解决方案您似乎已经回答了你自己的问题。如果你的code需要不支持旧的系统上运行
的popen
打开双向管道,那么你将无法使用的popen
(至少不是的提供的)。真正的问题是关于有问题的旧系统中的确切功能。尤其是,他们确实
管道
支持创建双向管?如果他们有一个管道
,可以创建一个双向的管道,但的popen
还是不行,那么我会写在code的主流使用的popen
与双向管道,并提供的popen
的的实现可以使用被在用在需要编制一个双向管道。如果您需要支持系统足够老了
管道
只支持单向的管道,那么你pretty多坚持使用管
,叉
,dup2
等,对你自己的。在工作的几乎的像一个现代版的的popen
但是,而不是返回一个文件句柄,填补了功能我可能还在包装这件事在一个小结构有两个文件句柄,一个孩子的标准输入
,其他孩子的标准输出
。I'm implementing piping on a simulated file system in C++ (with mostly C). It needs to run commands in the host shell but perform the piping itself on the simulated file system.
I could achieve this with the
pipe()
,fork()
, andsystem()
system calls, but I'd prefer to usepopen()
(which handles creating a pipe, forking a process, and passing a command to the shell). This may not be possible because (I think) I need to be able to write from the parent process of the pipe, read on the child process end, write the output back from the child, and finally read that output from the parent. The man page forpopen()
on my system says a bidirectional pipe is possible, but my code needs to run on a system with an older version supporting only unidirectional pipes.With the separate calls above, I can open/close pipes to achieve this. Is that possible with
popen()
?For a trivial example, to run
ls -l | grep .txt | grep cmds
I need to:
- Open a pipe and process to run
ls -l
on the host; read its output back- Pipe the output of
ls -l
back to my simulator- Open a pipe and process to run
grep .txt
on the host on the piped output ofls -l
- Pipe the output of this back to the simulator (stuck here)
- Open a pipe and process to run
grep cmds
on the host on the piped output ofgrep .txt
- Pipe the output of this back to the simulator and print it
man popen
From Mac OS X:
The
popen()
function 'opens' a process by creating a bidirectional pipe, forking, and invoking the shell. Any streams opened by previouspopen()
calls in the parent process are closed in the new child process. Historically,popen()
was implemented with a unidirectional pipe; hence, many implementations ofpopen()
only allow the mode argument to specify reading or writing, not both. Becausepopen()
is now implemented using a bidirectional pipe, the mode argument may request a bidirectional data flow. The mode argument is a pointer to a null-terminated string which must be 'r' for reading, 'w' for writing, or 'r+' for reading and writing.
解决方案You seem to have answered your own question. If your code needs to work on an older system that doesn't support
popen
opening bidirectional pipes, then you won't be able to usepopen
(at least not the one that's supplied).The real question would be about the exact capabilities of the older systems in question. In particular, does their
pipe
support creating bidirectional pipes? If they have apipe
that can create a bidirectional pipe, butpopen
that doesn't, then I'd write the main stream of the code to usepopen
with a bidirectional pipe, and supply an implementation ofpopen
that can use a bidirectional pipe that gets compiled in an used where needed.If you need to support systems old enough that
pipe
only supports unidirectional pipes, then you're pretty much stuck with usingpipe
,fork
,dup2
, etc., on your own. I'd probably still wrap this up in a function that works almost like a modern version ofpopen
, but instead of returning one file handle, fills in a small structure with two file handles, one for the child'sstdin
, the other for the child'sstdout
.这篇关于可以popen()完成建立双向管道像管()+ fork()的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!