|laziness, impatience, and hubris|
IPC::Run::run and bufferingby rovf (Priest)
|on Jun 14, 2012 at 08:44 UTC||Need Help??|
rovf has asked for the
wisdom of the Perl Monks concerning the following question:
I have an application, which uses IPC::Run in the following way:
I have no information about $cmd - can be anything, and it is not on my control. Now my question:
Under the assumption that $cmd does not do unbuffered output, and doesn't fiddle around with buffering by itself (think of: just doing C style fwrite calls), is there a way I can control the buffer size (i.e. make it larger) of the pipe from the Perl side?
The code is currently executed on Windows and Linux. I understand that if there is at all a solution to my problem, it probably will look different on both platforms. This is OK. I'm not very optimistic, that a solution to this problem exist, but I don't know enough about the operating system internals.
Another idea which came to my mind, would be to replace the "IPC::Run::run" by an open(my $pipe,"$cmd ...|") and read from this pipe to my application, which then writes the output in larger chunks. This should work at least on Linux (possibly not Windows, because Windows does not, AFIK, support real pipes and needs to simulate them using files). However, if there were a solution of just increasing the buffer size for the output redirection, I would prefer that.UPDATE:
I would like to sketch a possible solution - maybe someone can see whether or not it should work: I replace the call to IPC::Run::run by a call to IPC::Run::start and collect the output via a function:
The function buffers the resulting lines, and if the number of characters exceeds a certain amount, it "flushes" the buffer by writing it to the output file. In order to bypass system-internal buffering, the output file is opened for writing using the :unix layer, and the data is written using syswrite instead of print. This is done in order to bypass stdio buffering. Of course this means that on Windows, I have to manually translate \n into 0x0d.0x0a manually. Does this sound reasonable? Is there a simpler way to do it?
Ronald Fischer <email@example.com>