Recent

Author Topic: TProcess EOF - CloseInput  (Read 680 times)

Snify

  • New Member
  • *
  • Posts: 13
TProcess EOF - CloseInput
« on: February 23, 2022, 03:37:50 pm »
Hello together :)

I have the following function to "read" a regular string from stdin:

Code: Pascal  [Select][+][-]
  1. function GetStdIn: string;
  2. var
  3.    tmp: string;
  4. begin
  5.   result := '';
  6.   while not EOF do begin
  7.     readln (tmp);
  8.     if EOF then begin
  9.       result:= result + tmp;
  10.     end else begin
  11.       result:= result + tmp + LineEnding;
  12.     end;
  13.   end;
  14. end;    

The full test program looks like this:

Code: Pascal  [Select][+][-]
  1. begin
  2.   writeln (StdErr, 'FIRST ERROR LINE');
  3.   writeln ('This line and the following stdin detection is on stdout');
  4.   writeln ('Stdin was:', LineEnding, GetStdIn);
  5.   writeln (StdErr, 'This is on stderror');
  6.   writeln ('Regular stdout again');
  7.   // end of program
  8. end.
                               
I am not sure if my function is correct.
This works like a charm if I use the above function in a shell like this:

Code: Pascal  [Select][+][-]
  1. printf "row1\nrow2\n..." | ./project1


However when I use the TProcess Class with the WriteInput Method, the process locks.

This is what I use to execute my program and try to read and write to the pipes:
(some of the code is taken from https://wiki.freepascal.org/Executing_External_Programs)


Code: Pascal  [Select][+][-]
  1. MyProcess               := TProcess.Create(NIL);    
  2. MyProcess.Executable    := 'project1'; // the program with the "GetStdIn" function
  3. MyProcess.Options               := MyProcess.Options + [poPassInput, poUsePipes];
  4. MyProcess.Execute;
  5. mystring                                := 'Hello Lazarus';
  6. MyProcess.Input.Write(mystring[1], Length(mystring));
  7. MyProcess.CloseInput; // does not trigger EOF?!
  8.  
  9. // NumBytesAvailable is always 0 for output and stderr
  10. while MyProcess.Running or (MyProcess.Output.NumBytesAvailable > 0) or
  11. (MyProcess.Stderr.NumBytesAvailable > 0) do
  12. begin
  13.     while MyProcess.Output.NumBytesAvailable > 0 do
  14.     begin
  15.         ReadCount := Min(512, MyProcess.Output.NumBytesAvailable); //Read up to buffer, not more
  16.         MyProcess.Output.Read(CharBuffer, ReadCount);
  17.     end;
  18.                                  
  19.     while MyProcess.Stderr.NumBytesAvailable > 0 do
  20.     begin
  21.         ReadCount := Min(512, MyProcess.Stderr.NumBytesAvailable); //Read up to buffer, not more
  22.         MyProcess.Stderr.Read(CharBuffer, ReadCount);
  23.     end;
  24. end;
  25. MyProcess.Free;
                                                                                 
The binary path etc. is simplified here and executes just as it should be.
If I remove the whole stdin stuff, it works just fine.

Can someone spot my error?

Thank you in advance

« Last Edit: February 23, 2022, 03:41:52 pm by Snify »

Snify

  • New Member
  • *
  • Posts: 13
Re: TProcess EOF - CloseInput
« Reply #1 on: February 23, 2022, 03:54:06 pm »
I just figured out the problem.
Thank you.

I needed to avoid "poPassInput".
This causes to use the stdin from the "parent" process instead of it's own stdin.

 

TinyPortal © 2005-2018