mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
changes FileHandle type on Windows (#24910)
On windows, `HANDLE` type values are converted to `syncio.FileHandle` in `lib/std/syncio.nim`, `lib/pure/memfiles.nim` and `lib/pure/osproc.nim`. `HANDLE` type is `void *` on Windows and its size is larger then `cint`. https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types This PR change `syncio.FileHandle` type so that converting `HANDLE` type to `syncio.FileHandle` doesn't lose bits. We can keep `FileHandle` unchanged and change some of parameter/return type from `FileHandle` to an type same size to `HANDLE`, but it is breaking change.
This commit is contained in:
@@ -46,10 +46,10 @@ proc setFileSize(fh: FileHandle, newFileSize = -1, oldSize = -1): OSErrorCode =
|
||||
when defined(windows):
|
||||
var sizeHigh = int32(newFileSize shr 32)
|
||||
let sizeLow = int32(newFileSize and 0xffffffff)
|
||||
let status = setFilePointer(fh, sizeLow, addr(sizeHigh), FILE_BEGIN)
|
||||
let status = setFilePointer(Handle fh, sizeLow, addr(sizeHigh), FILE_BEGIN)
|
||||
let lastErr = osLastError()
|
||||
if (status == INVALID_SET_FILE_POINTER and lastErr.int32 != NO_ERROR) or
|
||||
setEndOfFile(fh) == 0:
|
||||
setEndOfFile(Handle fh) == 0:
|
||||
result = lastErr
|
||||
else:
|
||||
if newFileSize > oldSize: # grow the file
|
||||
|
||||
@@ -845,11 +845,11 @@ when weirdTarget or defined(windows) or defined(posix) or defined(nintendoswitch
|
||||
result = default(FileInfo)
|
||||
when defined(windows):
|
||||
var rawInfo: BY_HANDLE_FILE_INFORMATION
|
||||
# We have to use the super special '_get_osfhandle' call (wrapped above)
|
||||
# We have to use the super special '_get_osfhandle' call (wrapped in winlean)
|
||||
# To transform the C file descriptor to a native file handle.
|
||||
var realHandle = get_osfhandle(handle)
|
||||
var realHandle = get_osfhandle(handle.cint)
|
||||
if getFileInformationByHandle(realHandle, addr rawInfo) == 0:
|
||||
raiseOSError(osLastError(), $handle)
|
||||
raiseOSError(osLastError(), $(int handle))
|
||||
rawToFormalFileInfo(rawInfo, "", result)
|
||||
else:
|
||||
var rawInfo: Stat = default(Stat)
|
||||
|
||||
@@ -546,8 +546,8 @@ when defined(windows) and not defined(useNimRtl):
|
||||
raiseOSError(osLastError())
|
||||
|
||||
proc fileClose[T: Handle | FileHandle](h: var T) {.inline.} =
|
||||
if h > 4:
|
||||
closeHandleCheck(h)
|
||||
if h.int > 4:
|
||||
closeHandleCheck(Handle h)
|
||||
h = INVALID_HANDLE_VALUE.T
|
||||
|
||||
proc hsClose(s: Stream) =
|
||||
@@ -574,8 +574,8 @@ when defined(windows) and not defined(useNimRtl):
|
||||
addr bytesWritten, nil)
|
||||
if a == 0: raiseOSError(osLastError())
|
||||
|
||||
proc newFileHandleStream(handle: Handle): owned FileHandleStream =
|
||||
result = FileHandleStream(handle: handle, closeImpl: hsClose, atEndImpl: hsAtEnd,
|
||||
proc newFileHandleStream(handle: FileHandle): owned FileHandleStream =
|
||||
result = FileHandleStream(handle: Handle handle, closeImpl: hsClose, atEndImpl: hsAtEnd,
|
||||
readDataImpl: hsReadData, writeDataImpl: hsWriteData)
|
||||
|
||||
proc buildCommandLine(a: string, args: openArray[string]): string =
|
||||
@@ -888,7 +888,7 @@ when defined(windows) and not defined(useNimRtl):
|
||||
assert readfds.len <= MAXIMUM_WAIT_OBJECTS
|
||||
var rfds: WOHandleArray
|
||||
for i in 0..readfds.len()-1:
|
||||
rfds[i] = readfds[i].outHandle #fProcessHandle
|
||||
rfds[i] = readfds[i].outHandle.Handle #fProcessHandle
|
||||
|
||||
var ret = waitForMultipleObjects(readfds.len.int32,
|
||||
addr(rfds), 0'i32, timeout.int32)
|
||||
@@ -904,7 +904,7 @@ when defined(windows) and not defined(useNimRtl):
|
||||
|
||||
proc hasData*(p: Process): bool =
|
||||
var x: int32
|
||||
if peekNamedPipe(p.outHandle, lpTotalBytesAvail = addr x):
|
||||
if peekNamedPipe(p.outHandle.Handle, lpTotalBytesAvail = addr x):
|
||||
result = x > 0
|
||||
|
||||
elif not defined(useNimRtl):
|
||||
|
||||
@@ -805,9 +805,13 @@ proc isatty*(f: File): bool =
|
||||
when defined(posix):
|
||||
proc isatty(fildes: FileHandle): cint {.
|
||||
importc: "isatty", header: "<unistd.h>".}
|
||||
else:
|
||||
proc isatty(fildes: FileHandle): cint {.
|
||||
elif defined(windows):
|
||||
proc c_isatty(fildes: cint): cint {.
|
||||
importc: "_isatty", header: "<io.h>".}
|
||||
proc isatty(fildes: FileHandle): cint =
|
||||
c_isatty(cint(fildes))
|
||||
else:
|
||||
{.error: "isatty is not supported on your operating system!".}
|
||||
|
||||
result = isatty(getFileHandle(f)) != 0'i32
|
||||
|
||||
|
||||
@@ -40,9 +40,6 @@ type
|
||||
## at the end. If the file does not exist, it
|
||||
## will be created.
|
||||
|
||||
FileHandle* = cint ## The type that represents an OS file handle; this is
|
||||
## useful for low-level file access.
|
||||
|
||||
FileSeekPos* = enum ## Position relative to which seek should happen.
|
||||
# The values are ordered so that they match with stdio
|
||||
# SEEK_SET, SEEK_CUR and SEEK_END respectively.
|
||||
@@ -50,6 +47,13 @@ type
|
||||
fspCur ## Seek relative to current position
|
||||
fspEnd ## Seek relative to end
|
||||
|
||||
when defined(windows):
|
||||
type FileHandle* = int
|
||||
## Windows `HANDLE` type, convertible to `winlean.Handle`.
|
||||
else:
|
||||
type FileHandle* = cint ## The type that represents an OS file handle; this is
|
||||
## useful for low-level file access.
|
||||
|
||||
# text file handling:
|
||||
when not defined(nimscript) and not defined(js):
|
||||
# duplicated between io and ansi_c
|
||||
@@ -310,12 +314,7 @@ elif defined(windows):
|
||||
proc getOsfhandle(fd: cint): int {.
|
||||
importc: "_get_osfhandle", header: "<io.h>".}
|
||||
|
||||
type
|
||||
IoHandle = distinct pointer
|
||||
## Windows' HANDLE type. Defined as an untyped pointer but is **not**
|
||||
## one. Named like this to avoid collision with other `system` modules.
|
||||
|
||||
proc setHandleInformation(hObject: IoHandle, dwMask, dwFlags: WinDWORD):
|
||||
proc setHandleInformation(hObject: FileHandle, dwMask, dwFlags: WinDWORD):
|
||||
WinBOOL {.stdcall, dynlib: "kernel32",
|
||||
importc: "SetHandleInformation".}
|
||||
|
||||
@@ -361,7 +360,7 @@ proc getFileHandle*(f: File): FileHandle =
|
||||
## Note that on Windows this doesn't return the Windows-specific handle,
|
||||
## but the C library's notion of a handle, whatever that means.
|
||||
## Use `getOsFileHandle` instead.
|
||||
c_fileno(f)
|
||||
FileHandle c_fileno(f)
|
||||
|
||||
proc getOsFileHandle*(f: File): FileHandle =
|
||||
## Returns the OS file handle of the file `f`. This is only useful for
|
||||
@@ -390,7 +389,7 @@ when defined(nimdoc) or (defined(posix) and not defined(nimscript)) or defined(w
|
||||
flags = if inheritable: flags and not FD_CLOEXEC else: flags or FD_CLOEXEC
|
||||
result = c_fcntl(f, F_SETFD, flags) != -1
|
||||
else:
|
||||
result = setHandleInformation(cast[IoHandle](f), HANDLE_FLAG_INHERIT,
|
||||
result = setHandleInformation(f, HANDLE_FLAG_INHERIT,
|
||||
inheritable.WinDWORD) != 0
|
||||
|
||||
proc readLine*(f: File, line: var string): bool {.tags: [ReadIOEffect],
|
||||
@@ -423,12 +422,18 @@ proc readLine*(f: File, line: var string): bool {.tags: [ReadIOEffect],
|
||||
importc: "LocalFree", stdcall, dynlib: "kernel32".}
|
||||
|
||||
proc isatty(f: File): bool =
|
||||
# terminal module also has isatty
|
||||
when defined(posix):
|
||||
proc isatty(fildes: FileHandle): cint {.
|
||||
importc: "isatty", header: "<unistd.h>".}
|
||||
else:
|
||||
proc isatty(fildes: FileHandle): cint {.
|
||||
elif defined(windows):
|
||||
proc c_isatty(fildes: cint): cint {.
|
||||
importc: "_isatty", header: "<io.h>".}
|
||||
proc isatty(fildes: FileHandle): cint =
|
||||
c_isatty(cint(fildes))
|
||||
else:
|
||||
{.error: "isatty is not supported on your operating system!".}
|
||||
|
||||
result = isatty(getFileHandle(f)) != 0'i32
|
||||
|
||||
# this implies the file is open
|
||||
@@ -769,10 +774,10 @@ proc open*(f: var File, filehandle: FileHandle,
|
||||
## The passed file handle will no longer be inheritable.
|
||||
when not defined(nimInheritHandles) and declared(setInheritable):
|
||||
let oshandle = when defined(windows): FileHandle getOsfhandle(
|
||||
filehandle) else: filehandle
|
||||
cint filehandle) else: filehandle
|
||||
if not setInheritable(oshandle, false):
|
||||
return false
|
||||
f = c_fdopen(filehandle, RawFormatOpen[mode])
|
||||
f = c_fdopen(cint filehandle, RawFormatOpen[mode])
|
||||
result = f != nil
|
||||
|
||||
proc open*(filename: string,
|
||||
|
||||
@@ -815,7 +815,7 @@ proc WSASendTo*(s: SocketHandle, buf: ptr TWSABuf, bufCount: DWORD,
|
||||
completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {.
|
||||
stdcall, importc: "WSASendTo", dynlib: "Ws2_32.dll".}
|
||||
|
||||
proc get_osfhandle*(fd:FileHandle): Handle {.
|
||||
proc get_osfhandle*(fd: cint): Handle {.
|
||||
importc: "_get_osfhandle", header:"<io.h>".}
|
||||
|
||||
proc getSystemTimes*(lpIdleTime, lpKernelTime,
|
||||
|
||||
Reference in New Issue
Block a user