freepascal - 如何检测 Windows 下 FreePascal 中的 stdin 或 stdout 是否重定向?

标签 freepascal io-redirection

我需要知道是否已使用最新的 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       = $0080;
  FASTCONSOLE  = $0010;
  CONSOUT      = $0002;
  CONSIN       = $0001;
asm
  mov     InOutRes,0
  mov     ax,$4400       { IOCTL svc, get device information }
  mov     bx,handle
  int     $21            { 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       = $0080;
      FASTCONSOLE  = $0010;
      CONSOUT      = $0002;
      CONSIN       = $0001;
asm
          movw      $0,InOutRes
          movw      $4400,%ax           { IOCTL svc, get device information }
          movw      handle,%bx
          int       $21                 { result in DX }
          movw      $1,%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 做什么应该是显而易见的。

关于freepascal - 如何检测 Windows 下 FreePascal 中的 stdin 或 stdout 是否重定向?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40709193/

相关文章:

range - 检查数字是否在 free pascal 的范围内

c++ - 来自 C++ DLL 的 Free Pascal 回调

linux - 一个文件输入到脚本中的两个程序

visual-studio - 当我从 Perl 调用 cl.exe 时,为什么不生成任何输出?

macos - 如何使用 Free Pascal 编译 64 位 Mac 程序?

interpreter - Free Pascal 有命令行解释器吗?

freepascal - 在 free pascal 中使用类似于\n的东西而不是空的 WriteLn()

c - 如何在C中使用重定向进行文件输入

c - 未检测到 Windows CreateProcess 退出

python - 为什么 subprocess.run 输出与同一命令的 shell 输出不同?