From: FangQ on 19 Sep 2009 12:57 thank you very much for all of the responses. I found all your comments very helpful and Marcel's example code worked beautifully for me. To answer the question about using popen and pipe together, I actually don't know other alternatives to save the output into a buffer, except running an external command via popen and read from it. Most of the examples I saw invoke exec* to pipe the data to an external process, but I don't have access (or know how to gain access) to the output. For Marcel's example, I am trying to understand the 3 dup2.calls, can some one commend on this? dup2(STDIN_FILENO, d[1]); /*make d[1] pipe be the stdin of the parent ?*/ dup2(d[0], STDIN_FILENO); close(d[0]); f = popen("tac", "r"); dup2(d[1], STDIN_FILENO); close(d[1]); thank you again Qianqian On Sep 19, 1:22 am, Barry Margolin <bar...(a)alum.mit.edu> wrote: > In article <h91mfh$mm...(a)aioe.org>, pac...(a)kosh.dhis.org (Alan Curry) > wrote: > > > In article <h91eoh$f1...(a)aioe.org>, I wrote: > > > >The next major thing is why are you using popen() at all? You already created > > >a pipe and a child process, you don't need yet another pipe and yet another > > >process (which is what popen gives you). > > > Correction: You do need another pipe (since you're piping in and out of the > > "tac" process) but you don't really need the extra process. > > You may need it to avoid deadlock. If the writer tries to write > everything to the send pipe before reading anything, the receive pipe's > buffer may fill up, and then the tac process would block, and stop > reading from the send pipe, so it will fill up and the writer will block. > > I don't think this can happen with a command like "tac", since it can't > start writing until it reads everything you send it. But it can happen > with other programs that produce output as they go (e.g. awk, grep, > sed). And even if you know the program produces one line of output for > each line of input, you can't solve it by doing alternating writes and > reads, because it's likely that the program uses stdio, which by default > does full buffering when output is to a pipe. > > Using separate processes (or threads) for writing and reading solves > this problem. You could also do it with select(), but that's a little > more complicated to code. > > -- > Barry Margolin, bar...(a)alum.mit.edu > Arlington, MA > *** PLEASE post questions in newsgroups, not directly to me *** > *** PLEASE don't copy me on replies, I'll read them in the group ***
From: Marcel Bruinsma on 19 Sep 2009 16:33 Am Samstag 19 September 2009 18:57, FangQ a écrit : > For Marcel's example, I am trying to understand the 3 dup2 > calls, can some one comment on this? > > dup2(STDIN_FILENO, d[1]); /*make d[1] pipe be the stdin > of the parent ?*/ Save the original stdin in d[1] (else it will be lost). I should have added, fcntl(d[1], F_SETFD, fcntl(d[1], F_GETFD)|FD_CLOEXEC); otherwise this copy of the original stdin will remain open in the 'tac' process created by popen(). > dup2(d[0], STDIN_FILENO); close(d[0]); Redirect stdin for the 'tac' command, which reads its input from stdin; and after duplicating d[0] (the read end of the pipe) to stdin, close d[0], because it is no longer needed in the parent. > f = popen("tac", "r"); Open 'tac' with stdin coming from the read end of the pipe, and stdout going to fileno(f). > dup2(d[1], STDIN_FILENO); close(d[1]); Restore the original stdin, which was saved in d[1], and then release the d[1] descriptor. -- printf -v email $(echo \ 155 141 162 143 145 154 142 162 165 151 \ 156 163 155 141 100 171 141 150 157 157 056 143 157 155|tr \ \\\\) # Live every life as if it were your last! #
First
|
Prev
|
Pages: 1 2 Prev: Need to use streams/buffers, but NOT related to stdin, stdoutor to files Next: mt |