In the case of OP, it appears a hack with Fortran intrinsic GET_ENVIRONMENT_VARIABLE
was adequate.
However if one wants to pursue more detailed IO and in a safer manner, then the option will be to make use of vendor-provided APIs and to investigate calling them from Fortran.
In the case of Microsoft Windows OS, the APIs would be 'GetTempPath,
GetTempFileName`, etc. as described at the Microsoft site e.g., GetTempFileName function (winbase.h) - Win32 apps | Microsoft Learn. These APIs are based on Microsoft C/C++ and are mostly compatible with Fortran facility toward interoperability with a C companion processor, in this case Microsoft C/C++ compiler.
One can then set up Fortran interfaces to these APIs and work with them in Fortran code, here’s a rather simple almost trivial but complete example of writing to a temporary file in the TEMP directory on Windows:
module clib_m
! C standard library functions
use, intrinsic :: iso_c_binding, only : c_size_t, c_char
interface
function strlen(s) result(slen) bind(C, name="strlen")
! <string.h>: strlen
import :: c_size_t, c_char
character(kind=c_char, len=1), intent(in) :: s(*)
! Function result
integer(c_size_t) :: slen
end function
end interface
end module
module IWinAPI_m
use, intrinsic :: iso_c_binding, only : DWORD => c_int, UINT => c_int, c_char, c_null_char
integer(DWORD), parameter :: MAX_PATH = 260
interface
function GetTempPath( nBufferLength, lpBuffer ) result(iret) bind(C, name="GetTempPathA")
!DIR$ ATTRIBUTES STDCALL :: GetTempPath
! c.f. https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
! Microsoft API
! DWORD GetTempPathA(DWORD nBufferLength, LPSTR lpBuffer);
import :: DWORD, c_char
! Argument list
integer(DWORD), intent(in), value :: nBufferLength
character(kind=c_char, len=1), intent(inout) :: lpBuffer(*)
! Function result
integer(DWORD) :: iret
!GCC$ ATTRIBUTES STDCALL :: GetTempPath
end function
function GetTempFileName( lpPathName, lpPrefixString, uUnique, lpTempFileName ) &
result(iret) bind(C, name="GetTempFileNameA")
!DIR$ ATTRIBUTES STDCALL :: GetTempFileName
! c.f. https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-gettempfilename
! Microsoft API
! UINT GetTempFileName( LPCTSTR lpPathName, LPCTSTR lpPrefixString, UINT uUnique,
! LPTSTR lpTempFileName);
import :: UINT, c_char
! Argument list
character(kind=c_char,len=1), intent(in) :: lpPathName(*)
character(kind=c_char,len=1), intent(in) :: lpPrefixString(*)
integer(UINT), intent(in), value :: uUnique
character(kind=c_char,len=1), intent(inout) :: lpTempFileName(*)
! Function result
integer(UINT) :: iret
!GCC$ ATTRIBUTES STDCALL :: GetTempFileName
end function
end interface
end module
use IWinAPI_m
use clib_m, only : strlen
integer(DWORD) :: irc
character(kind=c_char, len=:), allocatable :: temp_path, temp_file, prefix_string
integer(UINT) :: lun
allocate ( character(kind=c_char, len=MAX_PATH+1) :: temp_path )
irc = GetTempPath( len(temp_path), temp_path )
if ( irc > 0 ) then
temp_path = temp_path(1:irc)
print *, "Temporary path name: ", temp_path
else
print *, "GetTempPath call failed."
end if
! Proceed assuming temp path name is less than MAX_PATH-14
prefix_string = c_char_"FOR" // c_null_char
lun = 0
allocate ( character(kind=c_char, len=MAX_PATH+1) :: temp_file )
irc = GetTempFileName( temp_path, prefix_string, lun, temp_file )
if ( irc > 0 ) then
temp_file = temp_file(1:strlen(temp_file))
print *, "Temporary file name: ", temp_file
else
print *, "GetTempFileName call failed."
end if
open( newunit=lun, file=temp_file, iostat=irc )
if ( irc /= 0 ) then
print *, "Error opening temporary file."
stop
end if
write( lun, fmt=*, iostat=irc ) "Hello World!"
if ( irc /= 0 ) then
print *, "Error opening temporary file."
stop
end if
close( lun, iostat=irc )
if ( irc /= 0 ) then
print *, "Error closing temporary file."
stop
end if
end
Here’s the execution output using gfortran for a Guest account on Windows; note the output of the temporary file is displayed separately.
C:\temp>gfortran -Wall -Wno-maybe-uninitialized -std=f2018 p.f90 -o gcc-p.exe
C:\temp>gcc-p.exe
Temporary path name: C:\Users\Guest\AppData\Local\Temp
Temporary file name: C:\Users\Guest\AppData\Local\Temp\FORF091.tmp
C:\temp>type “C:\Users\Guest\AppData\Local\Temp\FORF091.tmp”
Hello World!
C:\temp>
Note also the above example relies on the Windows API to create as well as name the temporary file in the appropriate temporary folder which is how the vendor would suggest the applications on Windows work with such temporary files.