[fpc-pascal] How to poll for a byte in Input?
tcoq
tcoq at free.fr
Sat Dec 10 14:58:04 CET 2011
Chad,
Thank you very much. I will try your approach, as I'm interested in the piping.
I also did some experimenting with SetConsoleMode, and also with SetFileAttributes, and with ReadFileEx. But no answer there. Still blocks.
Best regards,
Thierry
----- Mail Original -----
De: "Chad Berchek" <ad100 at vobarian.com>
À: "FPC-Pascal users discussions" <fpc-pascal at lists.freepascal.org>
Envoyé: Samedi 10 Décembre 2011 04h37:51 GMT +01:00 Amsterdam / Berlin / Berne / Rome / Stockholm / Vienne
Objet: Re: [fpc-pascal] How to poll for a byte in Input?
On 12/9/2011 9:44 AM, tcoq wrote:
> Hello,
> I'm trying to poll the input stream to see whether there is a new character available, without blocking my software.
Maybe TInputPipeStream.NumBytesAvailable can help. You can find it in
the documentation of the Pipes unit.
I tried an experiment to make sure it would work. I included the code
for the experiment below. It works when stdin is from another process.
It does not seem to work if stdin is from the console and I'm not sure
why. I tried adding the Windows API call SetConsoleMode(StdInputHandle,
1) to disable line-input mode but it didn't seem to make any difference.
Regarding WaitForSingleObject, there are some comments on the MSDN
documentation page regarding the use of this function for console input.
In particular, one observation was that if the console is in line-input
mode, WaitForSingleObject can return but ReadConsole will still block
until a carriage return is entered. Perhaps the same is true for
ReadFile. I have not tested this. See:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29.aspx
Code for the test: There are two programs. You can run WriteToPipe to
see writing to the stdin stream of one process from another process. You
can also test piped input using TestPipes by typing a command like:
type TestPipes.pas | TestPipes
However this does not seem to work:
TestPipes < TestPipes.pas
I don't know why exactly it doesn't appear to work with redirected input
from a file or from the console. By the way, I'm using Windows XP Pro
64-bit. Here is the test code.
----- WriteToPipe.pas -----
program WriteToPipe;
{$MODE ObjFpc}
uses
SysUtils,
Process,
Windows;
var
AProc: TProcess;
AString: string;
ACount: Integer;
begin
WriteLn('This will take about 20 seconds.');
AProc := TProcess.Create(nil);
try
AProc.CommandLine := 'TestPipes.exe';
AProc.Options := [poUsePipes];
AProc.Execute;
try
for ACount := 0 to 5 do
begin
AString := IntToStr(ACount);
AProc.Input.WriteBuffer(AString[1], Length(AString));
Sleep (3000);
end;
finally
AProc.Terminate(0);
end;
finally
AProc.Free;
end;
end.
----- End -----
----- TestPipes.pas -----
program TestPipes;
{$MODE ObjFpc}
uses
Classes,
Pipes,
SysUtils,
Windows;
var
AStream: TInputPipeStream;
AString: string;
AFile: TextFile;
begin
Assign(AFile, 'output.txt');
Rewrite(AFile);
try
AStream := TInputPipeStream.Create(StdInputHandle);
while True do
begin
if AStream.NumBytesAvailable > 0 then
begin
SetLength(AString, AStream.NumBytesAvailable);
AStream.ReadBuffer(AString[1], Length(AString));
WriteLn(AFile, 'I just got this: ', AString);
end else
begin
WriteLn(AFile, 'Waiting...');
Sleep(1000);
end;
end;
finally
Close(AFile);
end;
end.
----- End -----
_______________________________________________
fpc-pascal maillist - fpc-pascal at lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
More information about the fpc-pascal
mailing list