fusion icon indicating copy to clipboard operation
fusion copied to clipboard

open(f: var File, filehandle: FileHandle) does not work on Windows

Open Clonkk opened this issue 5 years ago • 3 comments
trafficstars

Opening a File from a FileHandle using

proc open*(f: var File, filehandle: FileHandle,
           mode: FileMode = fmRead): bool {.tags: [], raises: [], benign.}

does not work on Windows but does on Linux.

Example

  import std/ioutils

  let file1 = open("dummy.txt", mode=fmWrite)
  let dupfile1fd = duplicate(file1.getFileHandle())
  var f : File
  doAssert(isNil(f))
  let res = open(f, dupfile1fd, mode=fmWrite)
  # Both fails
  doAssert(not isNil(f)) # f == nil
  doAssert(res) # res == false
  let msg = "This is a test message that will be displayed ! \n"
  f.write(msg)
  f.close()

Current Output

Error: unhandled exception: test.nim(9, 9) `not isNil(f)`  [AssertionDefect]
Error: execution of an external program failed'

Expected Output

This is a test message that will be displayed ! 

Additional Information

Works on Linux

On branch devel commit ea6c28249ae7107fba954f90dac31132564dcaad

Clonkk avatar Oct 26 '20 18:10 Clonkk

  • doAssert(res) # res == -1 => you mean res == false

  • can you check whether it returns false directly here:

  when not defined(nimInheritHandles) and declared(setInheritable):
    let oshandle = when defined(windows): FileHandle getOsfhandle(filehandle) else: filehandle
    if not setInheritable(oshandle, false):
      return false
  • f = c_fdopen(filehandle, FormatOpen[mode]) if this fails, you need to check errno (and strerror) => what are the values here?

timotheecour avatar Oct 27 '20 00:10 timotheecour

Modified tests to include errno :

var errno {.importc, header: "<errno.h>".}: cint ## error variable
proc strerror(errnum: cint): cstring {.importc, header: "<string.h>".}

proc proc0()=
  let file1 = open("dummy.txt", mode=fmWrite)
  let dupfile1fd = duplicate(file1.getFileHandle())

  var f : File
  doAssert(isNil(f))
  let res = open(f, dupfile1fd, mode=fmWrite)
  let msg = "errno: " & $errno & " `" & $strerror(errno) & "`"

  doAssert(not isNil(f))
  doAssert(res)

  write(f, msg)
  close(f)

proc0()

Output errno: 22 `Invalid argument.

I tried using getOsFileHandle instead of getFileHandle as well

let dupfile1fd = duplicate(file1.getOsFileHandle())

Output:

Error: unhandled exception: Bad file descriptor [IOError]

Clonkk avatar Oct 27 '20 10:10 Clonkk

Since ioutils have moved to fusion, could the examples posted be changed? Or transfer this issue to fusion repo.

ringabout avatar Nov 04 '20 05:11 ringabout