Closed pichi closed 8 years ago
This is currently not supported. I am not sure if closing the pipe's output end of the parent process (erlexec
) will in fact signal the end of file in the spawned child (tac
). The first example is different from the second, because in the second case the tac
is invoked by the command shell via popen()
versus execv()
invocation in the first case.
You can try to introduce a new command in exec.cpp
that will lookup the pid of the child process state, close the writing end of the pipe, and see if it triggers the OS to close the corresponding stdin
end of the pipe in the child process. If so, you are welcome to send a PR.
The first example is different from the second, because in the second case the
tac
is invoked by the command shell viapopen()
versusexecv()
invocation in the first case.
It is actually exact way how the shell is doing it. It opens pipe by popen()
and then it calls execve()
in child. How do you think shell executes tac
? :-)
I would think the shell does it differently - via the pipe/fork/exec combination since popen()
only returns a stream, and as the result the child is already spawned so there's no need to call execve()
explicitly. I haven't looked at the library sources for the popen()
, but I am nearly certain that it's got the execve()
call in its implementation.
From the manual:
The
popen()
function opens a process by creating a pipe, forking, and invoking the shell.
popen()
is just a function which does all those steps for you but the mechanism behind is exactly same.
From BSD: http://www.retro11.de/ouxr/211bsd/usr/src/lib/libc/gen/popen.c.html
Exactly same shit :)
Unfortunately, I'm not familiar with C++ only C.
Nice:
1> application:start(erlexec).
ok
2> Watcher = spawn(fun F() -> receive Msg -> io:format("Got: ~p~n", [Msg]), F() end end).
<0.112.0>
3> {ok, Pid, OsPid} = exec:run("tac", [stdin, {stdout, Watcher}, {stderr, Watcher}]).
{ok,<0.114.0>,26143}
4> exec:send(Pid, <<"foo\n">>).
ok
5> exec:send(Pid, <<"bar\n">>).
ok
6> exec:send(Pid, <<"baz\n">>).
ok
7> exec:send(Pid, eof).
ok
Got: {stdout,26143,<<"baz\nbar\nfoo\n">>}
I can't get it why they can't implement it in Erlang OTP as well.
13 tests, 0 failures
:)
Yes, that exec:send(Pid, eof).
makes sense, since it signifies the consumer's end of an end of input.
None of the examples cover how to close stdin after providing custom generated input. For example calling
tac
.And what I am supposed to do now?
exec:manage/2
doesn't do the trick:I am missing command for closing stdin of the existing and opened stdin of the existing command.
Compare with
exec:run("echo -e 'foo\\nbar\\nbaz' | tac", [{stdout, Watcher}, {stderr, Watcher}]).