如何检测 Windows 下的 FreePascal 中是否重定向了标准输入或标准输出?
How do I detect if stdin or stdout is redirected in FreePascal under Windows?
我需要知道是否已使用最新的 FPC (v3.0.0) 为控制台应用程序重定向 stdin 或 stdout
在过去的 Turbo Pascal 时代,我有一个用汇编语言编写的函数可以做到这一点。见下文:
{ **************************************************************
* Routine : RedirectedStd *
* Purpose : Return Yes (True) if standard handle is being *
* : redirected. *
* Note(s) : Even though handle can take any handle value, *
* : the function will be meaningful only for the *
* : standard input, standard output, and standard *
* : error. It will, however, be True for any *
* : handle that does NOT point to the console. *
* : (Besides, this is what it actually checks for.)*
* : Make sure handle belongs to an open file or *
* : you will get wrong answer (check IOResult). *
************************************************************** }
function RedirectedStd(handle: Word): Boolean; assembler;
const
DEVICE = [=11=]80;
FASTCONSOLE = [=11=]10;
CONSOUT = [=11=]02;
CONSIN = [=11=]01;
asm
mov InOutRes,0
mov ax,00 { IOCTL svc, get device information }
mov bx,handle
int { result in DX }
mov ax,1 { assume function is True }
jc @Error { got error with code in AX }
test dx,DEVICE
jz @Out
test dx,FASTCONSOLE
jz @Out
test dx,CONSOUT
jz @Out
test dx,CONSIN
jz @Out
xor ax,ax { function is False }
jmp @Out
@Error:
mov InOutRes,ax
@Out:
end; { RedirectedStd }
此语法对 FPC 汇编程序无效。我尝试了以下变体,尽管编译正常但它崩溃了:
function RedirectedStd(handle: Word): Boolean; assembler;
label Error,Done;
const DEVICE = [=12=]80;
FASTCONSOLE = [=12=]10;
CONSOUT = [=12=]02;
CONSIN = [=12=]01;
asm
movw [=12=],InOutRes
movw 00,%ax { IOCTL svc, get device information }
movw handle,%bx
int { result in DX }
movw ,%ax { assume function is True }
jc Error { got error with code in AX }
test DEVICE,%dx
jz Done
test FASTCONSOLE,%dx
jz Done
test CONSOUT,%dx
jz Done
test CONSIN,%dx
jz Done
xor %ax,%ax { function is False }
jmp Done
Error: movw %ax,InOutRes
Done:
end; { RedirectedStd }
(不确定我的转换是否等效。)
有什么想法吗?
编辑:
根据公认的答案,它给了我足够的方向来找出解决方案,我想出了以下替代我原来例程的方法:
function RedirectedStd(handle: Word): Boolean; {$ifndef WINDOWS} unimplemented; {$endif}
begin
RedirectedStd := False;
{$ifdef WINDOWS}
case handle of
0: RedirectedStd := GetFileType(GetStdHandle(STD_INPUT_HANDLE)) <> FILE_TYPE_CHAR;
1: RedirectedStd := GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) <> FILE_TYPE_CHAR;
2: RedirectedStd := GetFileType(GetStdHandle(STD_ERROR_HANDLE)) <> FILE_TYPE_CHAR;
end;
{$endif}
end; { RedirectedStd }
哦,你需要使用 Windows;
使用
GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
用于标准输出。为 stdin 做什么应该是显而易见的。
我需要知道是否已使用最新的 FPC (v3.0.0) 为控制台应用程序重定向 stdin 或 stdout
在过去的 Turbo Pascal 时代,我有一个用汇编语言编写的函数可以做到这一点。见下文:
{ **************************************************************
* Routine : RedirectedStd *
* Purpose : Return Yes (True) if standard handle is being *
* : redirected. *
* Note(s) : Even though handle can take any handle value, *
* : the function will be meaningful only for the *
* : standard input, standard output, and standard *
* : error. It will, however, be True for any *
* : handle that does NOT point to the console. *
* : (Besides, this is what it actually checks for.)*
* : Make sure handle belongs to an open file or *
* : you will get wrong answer (check IOResult). *
************************************************************** }
function RedirectedStd(handle: Word): Boolean; assembler;
const
DEVICE = [=11=]80;
FASTCONSOLE = [=11=]10;
CONSOUT = [=11=]02;
CONSIN = [=11=]01;
asm
mov InOutRes,0
mov ax,00 { IOCTL svc, get device information }
mov bx,handle
int { result in DX }
mov ax,1 { assume function is True }
jc @Error { got error with code in AX }
test dx,DEVICE
jz @Out
test dx,FASTCONSOLE
jz @Out
test dx,CONSOUT
jz @Out
test dx,CONSIN
jz @Out
xor ax,ax { function is False }
jmp @Out
@Error:
mov InOutRes,ax
@Out:
end; { RedirectedStd }
此语法对 FPC 汇编程序无效。我尝试了以下变体,尽管编译正常但它崩溃了:
function RedirectedStd(handle: Word): Boolean; assembler;
label Error,Done;
const DEVICE = [=12=]80;
FASTCONSOLE = [=12=]10;
CONSOUT = [=12=]02;
CONSIN = [=12=]01;
asm
movw [=12=],InOutRes
movw 00,%ax { IOCTL svc, get device information }
movw handle,%bx
int { result in DX }
movw ,%ax { assume function is True }
jc Error { got error with code in AX }
test DEVICE,%dx
jz Done
test FASTCONSOLE,%dx
jz Done
test CONSOUT,%dx
jz Done
test CONSIN,%dx
jz Done
xor %ax,%ax { function is False }
jmp Done
Error: movw %ax,InOutRes
Done:
end; { RedirectedStd }
(不确定我的转换是否等效。)
有什么想法吗?
编辑: 根据公认的答案,它给了我足够的方向来找出解决方案,我想出了以下替代我原来例程的方法:
function RedirectedStd(handle: Word): Boolean; {$ifndef WINDOWS} unimplemented; {$endif}
begin
RedirectedStd := False;
{$ifdef WINDOWS}
case handle of
0: RedirectedStd := GetFileType(GetStdHandle(STD_INPUT_HANDLE)) <> FILE_TYPE_CHAR;
1: RedirectedStd := GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) <> FILE_TYPE_CHAR;
2: RedirectedStd := GetFileType(GetStdHandle(STD_ERROR_HANDLE)) <> FILE_TYPE_CHAR;
end;
{$endif}
end; { RedirectedStd }
哦,你需要使用 Windows;
使用
GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
用于标准输出。为 stdin 做什么应该是显而易见的。