more useful popen() function
Imported from http://bugzilla.roxen.com/bugzilla/show_bug.cgi?id=3327
Reported by Dan Nelson dnelson_1901@yahoo.com
Process.popen("command") is quite limited in that it blocks until the command completes, cannot be used to write to a pipe (i.e. popen("sendmail user@host"), and because it returns a string, cannot process large amounts of input.
The previous behaviour of popen can be duplicated with popen("command")->read().
//! Open a "process" for reading or writing. The @[command] is executed
//! as a shell statement ("/bin/sh -c command" for Unix,
//! "cmd /c command" for Windows). The parameter @[mode] should
//! be one of the following letters:
//! @string
//! @value 'r'
//! Open for reading. Data written by the process to stdout
//! is available for read.
//! @value 'w'
//! Open for writing. Data written to the file is available
//! to the process on stdin.
//! @endstring
//! If no @[mode] is passed, read mode is assumed.
object(Stdio.FILE) popen(string s, string|void mode)
{
if (!mode) mode = "r";
object f = Stdio.FILE();
if (!f) error("Popen failed. (couldn't create file)\n");
object p = f->pipe();
if(!p) error("Popen failed. (couldn't create pipe)\n");
if (mode == "w")
Process.spawn(s, p, 0, 0, destruct, f);
else
Process.spawn(s, 0, p, 0, destruct, f);
p->close();
destruct(p);
return f;
}