mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-07 13:33:22 +00:00
Update syncio.nim, fixes "open by FileHandle" doesn't work on Windows (#23456)
## Reprodution
if on Windows:
```Nim
when defined(windows):
var file: File
let succ = file.open(<aFileHandle>)
```
then `succ` will be false.
If tested, it can be found to fail with errno `22` and message: `Invalid
argument`
## Problem
After some investigations and tests,
I found it's due to the `mode` argument for `fdopen`.
Currently `NoInheritFlag`(`'N'` in Windows) is added to `mode` arg
passed to `_fdopen`, but if referring to
[Windows `_fdopen`
doc](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fdopen-wfdopen?view=msvc-170),
you'll find there is no `'N'` describled. That's `'N'` is not accepted
by `_fdopen`.
Therefore, the demo above will fail.
## In Addition
To begin with, technologically speaking, when opening with a
`fileHandle`(or called `fd`), there is no concept of fd-inheritable as
`fd` is opened already.
In POSIX, `NoInheritFlag` is defined as `e`.
It's pointed out in [POSIX `open`
man-doc](https://www.man7.org/linux/man-pages/man3/fopen.3.html) that
`e` in mode is ignored for fdopen(),
which means `e` for `fdopen()` is not wanted, just allowed.
Therefore, better to also not pass `e` to `fdopen`
---
In all, that's this PR.
(cherry picked from commit dee55f587f)
This commit is contained in:
@@ -648,6 +648,9 @@ const
|
||||
""
|
||||
else:
|
||||
""
|
||||
RawFormatOpen: array[FileMode, cstring] = [
|
||||
# used for open by FileHandle, which calls `fdopen`
|
||||
cstring("rb"), "wb", "w+b", "r+b", "ab"]
|
||||
FormatOpen: array[FileMode, cstring] = [
|
||||
cstring("rb" & NoInheritFlag), "wb" & NoInheritFlag, "w+b" & NoInheritFlag,
|
||||
"r+b" & NoInheritFlag, "ab" & NoInheritFlag
|
||||
@@ -749,7 +752,7 @@ proc open*(f: var File, filehandle: FileHandle,
|
||||
filehandle) else: filehandle
|
||||
if not setInheritable(oshandle, false):
|
||||
return false
|
||||
f = c_fdopen(filehandle, FormatOpen[mode])
|
||||
f = c_fdopen(filehandle, RawFormatOpen[mode])
|
||||
result = f != nil
|
||||
|
||||
proc open*(filename: string,
|
||||
|
||||
Reference in New Issue
Block a user