The agent reuses ExternalProgram class from liby2util, class Process is derived from ExternalProgram and adds stderr reading/writing, output buffering and a posibility to send a specified signal.
The complete path description is available in the autodocs/ directory.
// start a subprocess, remember the id integer id = (integer)(SCR::Execute(.process.start_shell, "/usr/bin/find /usr -type d")); string line = ""; while(SCR::Read(.process.running, id) == true) { // read stderr line = (string)SCR::Read(.process.read_line_stderr, id); if (line != nil) { y2warning("Error: %1", line); } // read stdout line = (string)SCR::Read(.process.read_line, id); if (line != nil) { // process the output here ... } else { // there was no output, wait for a while // give the subprocess time to print something // NOTE: change the constand in respect to the running command, // increase it for processes which print few lines sleep(20); } ret = (symbol) UI::PollInput(); // check if the abort button was pressed if (ret == `abort) { SCR::Execute(.process.kill, id); // kill the subprocess break; } } // process the remaining lines in the stdout buffer while (line != nil); { UI::ChangeWidget(`id(`dir), `Value, line); line = (string)SCR::Read(.process.read_line, id); } // process the stderr buffer here ...
The agent can start a subprocess in two ways
Note that the arguments are passed differently in each case. Shell execution requires the argument in the command, the arguments must be escaped to be processes correctly. The direct execution uses an optional map, the arguments are passed as a list of strings at key "args". In this case the armunets need not to be escpaed.
Example:
Start echo "\"foo bar\"" command:
When a subprocess produces too much output which is not read it is stopped when the buffers are full. (In my test it was about after 64kB, but this is system dependent.)
So it is a good idea to read the output regularly. It is possible to read the output (using .process.read(_line) and .process.read_stderr(_line) paths) when the process is running or just read the output to the internal buffers in the agent (using Read(.process.running), in addition to checking the status it read the outputs) and read them later at once when the process is finished.
Ladislav Slezák <lslezak@novell.com>