This is the guts of code that works on Linux. Broadly speaking, it is good enough to run a shell interactively which includes running a nested copy of the Lazarus IDE so that nested programs can be debugged.
...
process.Options := [poUsePipes];
process.Execute;
Sleep(100);
while process.Running or not ((process.Output.NumBytesAvailable = 0) and
(process.StdErr.NumBytesAvailable = 0)) do
if WorkerThread.Keypressed() then begin
buffer := WorkerThread.ReadKey();
process.Input.Write(buffer[1], 1)
end else begin
count := process.Output.NumBytesAvailable;
if count > 255 then
count := 255;
if count > 0 then begin
SetLength(buffer, count);
process.Output.Read(buffer[1], count);
(* The necessity of expanding LF to CRLF (\n to \r\n) might depend on the *)
(* terminal type, specified above to be "dumb". *)
buffer := AnsiReplaceStr(buffer, #$0a, #$0d + #$0a);
WorkerThread.WriteWindowed(buffer)
end else begin
count := process.StdErr.NumBytesAvailable;
if count > 255 then
count := 255;
if count > 0 then begin
SetLength(buffer, count);
process.StdErr.Read(buffer[1], count);
buffer := AnsiReplaceStr(buffer, #$0a, #$0d + #$0a);
WorkerThread.WriteWindowed(buffer)
end else
Sleep(10)
end
end
You can ignore the references to a different thread, they're only there since this is actually being run by a background thread with GUI interaction via Synchronize(). Obviously the specific I/O routines are app-specific as well, but this should be a reasonable demo of how to interact with the TProcess etc.
MarkMLl