Mark Robinson
Mark Robinson

Reputation: 953

Redmon & capturing stdin with Delphi

I am using redmon to redirect postscript to delphi for processing.

I am using the following code to read stdin to a file:

var
  Stdin: THandleStream;
  FStream: TFileStream;
  BytesRead:Int64;
  Buffer: array[0..1023] of Byte; 

StdIn := THandleStream.Create(GetStdHandle(STD_INPUT_HANDLE));
try
  tempps:=GetTempFile('.ps');
  FStream:=tfilestream.Create(tempps,fmCreate or fmOpenReadWrite);
  StdIn.Seek(0,0);
  try
    repeat
      BytesRead:=StdIn.Read(Buffer,1024);
      FStream.Write(Buffer,BytesRead);
    until bytesread<SizeOf(Buffer);
  finally
    InputSize:=FStream.Size;
    FStream.Free;
  end;
finally
  StdIn.Free;
end;

This works for most cases, except one where the redmon log file shows:

REDMON WritePort: OK  count=65536 written=65536

REDMON WritePort: Process not running. Returning TRUE.
    Ignoring 65536 bytes

Is the fact that it's 65536 just a red herring, and it's that I'm not properly reading stdin, or is there some weird limit somewhere I've overlooked?

Thanks in advance.

Edit 1

The 65536 is a red herring - redmon prints this message every 64k in the log, the entire file is 688759 bytes, however is does look like redmon closes output early, but then still continues to output more text anyway.

Upvotes: 1

Views: 1653

Answers (1)

kludg
kludg

Reputation: 27493

I don't know how RedMon works, but I would not rely on bytesread<SizeOf(Buffer) as EOF condition, because I suppose you are actually reading from a pipe, and ReadFile function as MSDN documentation says can return the number of bytes read less than the number of bytes to read if you are reading from a pipe.

BytesRead <= 0 condition is more reliable (it can fail only if RedMon will write 0 bytes on the other side of the pipe, I suppose it should not do it):

repeat
  BytesRead:=StdIn.Read(Buffer,1024);
  if BytesRead > 0 then
    FStream.WriteBuffer(Buffer,BytesRead);
until BytesRead <= 0;

Upvotes: 3

Related Questions