status of stdout

status of stdout

 

On windows 7, using intel fortran 17.1, is there a way in Fortran to determine in stdout has been redirected to a file, or stdout is going to a console window, or (it seems) to the console window and a file?   On win32, redirecting stdout results in stdout text going to the console window and to the stdout file.  On migrating from Win32 to  x64, stdout redirected only goes to the file and not to the console window.  We'd like to have the text going to both the console window and (if stdout is redirected) to the file.  It seems we'd need to know if stdout was redirected to be able to make things work this way.  Any suggestions would be appreciated.

thanks,  scott

5 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Rather than modifying your Fortran program, perhaps it may be easier to use an external solution?  See notes about "tee", "wintee", and other information in https://stackoverflow.com/questions/796476/displaying-windows-command-pr...

Thank you,

Eugene

 

Eugene Epshteyn

Quote:

On win32, redirecting stdout results in stdout text going to the console window and to the stdout file.

This is news to me.  Do you have an example?

 

Not a simple example I can put here.  It isn't code I wrote, but from the author:

When I first wrote Win32 NGTK, I was surprised that the AllocConsole() command worked to redirect standard out to the console window and to a file. I thought I needed to do more. I found this Windows command, put it in, it worked.

 

When porting the windows gui from Win32 to x64, we instead found:

On x64, the similar windows logic has stdout only going to a file when there is a > redirection and not to the console window.

 

scott

 

I cannot reproduce the splitting of output with AllocConsole, compiling the attached program using 17.0.4 or 18 beta update 1, compiling to a 32 bit or 64 bit windows target (running all variants of the executable on a 64 bit machine).  I compile and run the program using one of the following lines:

rc gui.rc && ifort /winapp GUI.f90 GUI.res && gui

rc gui.rc && ifort /winapp GUI.f90 GUI.res && gui > test.txt

(I can't attach the gui.rc file --- here it is inline)

#define IDD_DIALOG                     1000
#define IDC_PRINTSOMETHING             1001
#define IDC_ALLOCCONSOLE               1002
#include "Winres.h"

IDD_DIALOG DIALOG  0, 0, 260, 40
STYLE DS_MODALFRAME | WS_POPUP | WS_SYSMENU | WS_CAPTION
CAPTION "AllocConsole test"
BEGIN
    PUSHBUTTON      "PrintSomething",IDC_PRINTSOMETHING, 20,10,60,20
    PUSHBUTTON      "AllocConsole",IDC_ALLOCCONSOLE, 100,10,60,20
    PUSHBUTTON      "Cancel",IDCANCEL, 180,10,60,20
END

What I observe is that if the standard output handle (here a Win32 API concept, not a Fortran concept) is redirected to a file by the calling process, Fortran output statements writing to the console (PRINT and WRITE (*...  ) always go to that file.

In the absence of redirection, if a console is not attached prior to the first output statement, then output goes to the bit bucket.

In the absence of redirection, if a console is attached prior to the first output statement, then output appears on that attached console.  If that console is then destroyed, output goes to the bit bucket.  If another console is attached, then I see a runtime error.

In terms of your original question, you can test whether the standard output handle has been redirected away from a console by trying to use the Win32 handle for standard output with a Win32 API that requires a console handle - for example:

!*******************************************************************************
!!
!> Little utility program to test whether the standard output handle 
!! has been redirected to something other than the console.

PROGRAM TestStdOutToConsole
  
  USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY: ERROR_UNIT
  USE IFWIN
  
  IMPLICIT NONE
  
  ! Win32 standard output handle for the process.
  INTEGER(HANDLE) :: stdout_handle
  
  ! Buffer for retrieving the console mode, if the output handle addresses 
  ! a console.
  INTEGER(DWORD) :: console_mode
  
  INTEGER(BOOL) :: bret       ! BOOL API result.
  
  !*****************************************************************************
  
  stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE)
  IF ( (stdout_handle == INVALID_HANDLE_VALUE)  &
      .OR. (stdout_handle == NULL) ) THEN
    WRITE (ERROR_UNIT, "('Invalid standard output handle.')")
  ELSE
    ! Try a console function on the standard handle.
    bret = GetConsoleMode(stdout_handle, LOC(console_mode))
    IF (bret == 0) THEN
      WRITE (ERROR_UNIT, "('Standard output handle is redirected.')")
    ELSE
      WRITE (ERROR_UNIT, "('Standard output handle goes to console.')")
    END IF
  END IF
  
END PROGRAM TestStdOutToConsole
>ifort /check:all /warn:all /standard-semantics TestStdOutToConsole.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on IA-32, Version 18.0.0.083 Beta Build 20170510
Copyright (C) 1985-2017 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:TestStdOutToConsole.exe
-subsystem:console
TestStdOutToConsole.obj

>TestStdOutToConsole.exe
Standard output handle goes to console.

>TestStdOutToConsole.exe > test.txt
Standard output handle is redirected.

The concepts above of standard handles, consoles and redirection are all to do with the Win32 API, not the standard Fortran language.

Attachments: 

AttachmentSize
Downloadapplication/octet-stream GUI.f908.31 KB

Leave a Comment

Please sign in to add a comment. Not a member? Join today