I'm trying to write a Pascal (Lazarus/FPC) program that is started by another program as a process. The caller (the Arena chess GUI) talks to my program using StdIn and StdOut.
First I used READLN in my program to get the text commands sent from the GUI and WRITELN to reply to them. That worked well except that my program would stop doing anything if the READLN had to wait for input from the GUI. Since I wanted the program to carry on working and only deal with commands as they arrived I had to change this.
So I changed the code to use:
...
var inpStream : TInputPipeStream;
...
inpStream := TInputPipeStream.Create(StdInputHandle);
...
if inpStream.NumBytesAvailable > 0 then begin
SetLength(s_buffer, inpStream.NumBytesAvailable);
inpStream.Read(s_buffer[1], length(s_buffer));
end;
...
That worked really well as it no longer paused for the read. But then the WRITELN stopped working: nothing gets sent back to the GUI. I thought maybe this would help:
...
var inpStream : TInputPipeStream;
outStream : TOutputPipeStream;
...
inpStream := TInputPipeStream.Create(StdInputHandle);
outStream := TOutputPipeStream.Create(StdOutputHandle);
...
if inpStream.NumBytesAvailable > 0 then begin
SetLength(s_buffer, inpStream.NumBytesAvailable);
inpStream.Read(s_buffer[1], length(s_buffer));
end;
...
outStream.Write(s_buffer, length(s_buffer));
But that makes it worse as now it doesn't read or write anything. So how can I have non-blocked input on StdIn while maintaining the ability to write to StdOut?