Completed Linux/Posix implementation of getFileInfo
Moved parts of getFileInfo into a helper template.
This commit is contained in:
parent
8af083c847
commit
79f0c66b4d
2 changed files with 44 additions and 23 deletions
|
|
@ -1771,7 +1771,8 @@ type
|
||||||
lastWriteTime: TTime # Time file was last modified/written to.
|
lastWriteTime: TTime # Time file was last modified/written to.
|
||||||
creationTime: TTime # Time file was created. Not supported on all systems!
|
creationTime: TTime # Time file was created. Not supported on all systems!
|
||||||
|
|
||||||
proc rawToFormalFileInfo(rawInfo, formalInfo): expr =
|
template rawToFormalFileInfo(rawInfo, formalInfo): expr =
|
||||||
|
## Transforms the native file info structure into the one nimrod uses.
|
||||||
## 'rawInfo' is either a 'TBY_HANDLE_FILE_INFORMATION' structure on Windows,
|
## 'rawInfo' is either a 'TBY_HANDLE_FILE_INFORMATION' structure on Windows,
|
||||||
## or a 'TStat' structure on posix
|
## or a 'TStat' structure on posix
|
||||||
when defined(Windows):
|
when defined(Windows):
|
||||||
|
|
@ -1786,7 +1787,7 @@ proc rawToFormalFileInfo(rawInfo, formalInfo): expr =
|
||||||
formalInfo.creationTime = toTime(rawInfo.ftCreationTime)
|
formalInfo.creationTime = toTime(rawInfo.ftCreationTime)
|
||||||
|
|
||||||
# Retrieve basic permissions
|
# Retrieve basic permissions
|
||||||
if (info.dwFileAttributes and FILE_ATTRIBUTE_READONLY) != 0'i32:
|
if (rawInfo.dwFileAttributes and FILE_ATTRIBUTE_READONLY) != 0'i32:
|
||||||
formalInfo.permissions = {fpUserExec, fpUserRead, fpGroupExec,
|
formalInfo.permissions = {fpUserExec, fpUserRead, fpGroupExec,
|
||||||
fpGroupRead, fpOthersExec, fpOthersRead}
|
fpGroupRead, fpOthersExec, fpOthersRead}
|
||||||
else:
|
else:
|
||||||
|
|
@ -1794,37 +1795,40 @@ proc rawToFormalFileInfo(rawInfo, formalInfo): expr =
|
||||||
|
|
||||||
# Retrieve basic file kind
|
# Retrieve basic file kind
|
||||||
result.kind = pcFile
|
result.kind = pcFile
|
||||||
if (info.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) != 0'i32:
|
if (rawInfo.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) != 0'i32:
|
||||||
formalInfo.kind = pcDir
|
formalInfo.kind = pcDir
|
||||||
if (info.dwFileAttributes and FILE_ATTRIBUTE_REPARSE_POINT) != 0'i32:
|
if (rawInfo.dwFileAttributes and FILE_ATTRIBUTE_REPARSE_POINT) != 0'i32:
|
||||||
formalInfo.kind = succ(result.kind)
|
formalInfo.kind = succ(result.kind)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
template checkAndIncludeMode(rawMode, formalMode: expr) =
|
||||||
|
if (rawInfo.st_mode and rawMode) != 0'i32:
|
||||||
|
formalInfo.permissions.incl(formalMode)
|
||||||
formalInfo.id = (rawInfo.st_dev, rawInfo.st_ino)
|
formalInfo.id = (rawInfo.st_dev, rawInfo.st_ino)
|
||||||
formalInfo.size = getFileSize(handle)
|
formalInfo.size = rawInfo.st_size
|
||||||
formalInfo.linkCount = BiggestInt(rawInfo.st_Nlink)
|
formalInfo.linkCount = rawInfo.st_Nlink
|
||||||
formalInfo.lastAccessTime = rawInfo.st_atime
|
formalInfo.lastAccessTime = rawInfo.st_atime
|
||||||
formalInfo.lastWriteTime = rawInfo.st_mtime
|
formalInfo.lastWriteTime = rawInfo.st_mtime
|
||||||
formalInfo.creationTime = rawInfo.st_ctime
|
formalInfo.creationTime = rawInfo.st_ctime
|
||||||
|
|
||||||
result.permissions = {}
|
result.permissions = {}
|
||||||
if (a.st_mode and S_IRUSR) != 0'i32: result.incl(fpUserRead)
|
checkAndIncludeMode(S_IRUSR, fpUserRead)
|
||||||
if (a.st_mode and S_IWUSR) != 0'i32: result.incl(fpUserWrite)
|
checkAndIncludeMode(S_IWUSR, fpUserWrite)
|
||||||
if (a.st_mode and S_IXUSR) != 0'i32: result.incl(fpUserExec)
|
checkAndIncludeMode(S_IXUSR, fpUserExec)
|
||||||
|
|
||||||
if (a.st_mode and S_IRGRP) != 0'i32: result.incl(fpGroupRead)
|
checkAndIncludeMode(S_IRGRP, fpGroupRead)
|
||||||
if (a.st_mode and S_IWGRP) != 0'i32: result.incl(fpGroupWrite)
|
checkAndIncludeMode(S_IWGRP, fpGroupWrite)
|
||||||
if (a.st_mode and S_IXGRP) != 0'i32: result.incl(fpGroupExec)
|
checkAndIncludeMode(S_IXGRP, fpGroupExec)
|
||||||
|
|
||||||
if (a.st_mode and S_IROTH) != 0'i32: result.incl(fpOthersRead)
|
checkAndIncludeMode(S_IROTH, fpOthersRead)
|
||||||
if (a.st_mode and S_IWOTH) != 0'i32: result.incl(fpOthersWrite)
|
checkAndIncludeMode(S_IWOTH, fpOthersWrite)
|
||||||
if (a.st_mode and S_IXOTH) != 0'i32: result.incl(fpOthersExec)
|
checkAndIncludeMode(S_IXOTH, fpOthersExec)
|
||||||
|
|
||||||
result.kind = pcFile
|
formalInfo.kind = pcFile
|
||||||
if S_ISDIR(s.st_mode): result.kind = pcDir
|
if S_ISDIR(rawInfo.st_mode): formalInfo.kind = pcDir
|
||||||
if S_ISLNK(s.st_mode): succ(result.kind)
|
if S_ISLNK(rawInfo.st_mode): formalInfo.kind.inc()
|
||||||
|
|
||||||
proc getFileInfo*(handle: THandle, result: var FileInfo) =
|
proc getFileInfo*(handle: TFileHandle, result: var FileInfo) =
|
||||||
## Retrieves file information for the file object represented by the given
|
## Retrieves file information for the file object represented by the given
|
||||||
## handle.
|
## handle.
|
||||||
##
|
##
|
||||||
|
|
@ -1833,7 +1837,10 @@ proc getFileInfo*(handle: THandle, result: var FileInfo) =
|
||||||
# Done: ID, Kind, Size, Permissions, Link Count
|
# Done: ID, Kind, Size, Permissions, Link Count
|
||||||
when defined(Windows):
|
when defined(Windows):
|
||||||
var rawInfo: TBY_HANDLE_FILE_INFORMATION
|
var rawInfo: TBY_HANDLE_FILE_INFORMATION
|
||||||
if getFileInformationByHandle(handle, addr rawInfo) == 0:
|
# We have to use the super special '_get_osfhandle' call (wrapped above)
|
||||||
|
# To transform the C file descripter to a native file handle.
|
||||||
|
var realHandle = get_osfhandle(handle)
|
||||||
|
if getFileInformationByHandle(realHandle, addr rawInfo) == 0:
|
||||||
osError(osLastError())
|
osError(osLastError())
|
||||||
rawToFormalFileInfo(rawInfo, result)
|
rawToFormalFileInfo(rawInfo, result)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1857,12 +1864,23 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo =
|
||||||
## exist, or when permission restrictions prevent the program from retrieving
|
## exist, or when permission restrictions prevent the program from retrieving
|
||||||
## file information, an error will be thrown.
|
## file information, an error will be thrown.
|
||||||
when defined(Windows):
|
when defined(Windows):
|
||||||
var handle = openHandle(path, followSymlink)
|
var
|
||||||
|
handle = openHandle(path, followSymlink)
|
||||||
|
rawInfo: TBY_HANDLE_FILE_INFORMATION
|
||||||
if handle == INVALID_HANDLE_VALUE:
|
if handle == INVALID_HANDLE_VALUE:
|
||||||
osError(osLastError())
|
osError(osLastError())
|
||||||
getFileInfo(handle, result)
|
if getFileInformationByHandle(handle, addr rawInfo) == 0:
|
||||||
|
osError(osLastError())
|
||||||
|
rawToFormalFileInfo(rawInfo, result)
|
||||||
discard closeHandle(handle)
|
discard closeHandle(handle)
|
||||||
else:
|
else:
|
||||||
var
|
var rawInfo: TStat
|
||||||
|
if followSymlink:
|
||||||
|
if lstat(path, rawInfo) < 0'i32:
|
||||||
|
osError(osLastError())
|
||||||
|
else:
|
||||||
|
if stat(path, rawInfo) < 0'i32:
|
||||||
|
osError(osLastError())
|
||||||
|
rawToFormalFileInfo(rawInfo, result)
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
|
||||||
|
|
@ -716,3 +716,6 @@ proc WSASend*(s: TSocketHandle, buf: ptr TWSABuf, bufCount: DWORD,
|
||||||
bytesSent: PDWord, flags: DWORD, lpOverlapped: POverlapped,
|
bytesSent: PDWord, flags: DWORD, lpOverlapped: POverlapped,
|
||||||
completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {.
|
completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {.
|
||||||
stdcall, importc: "WSASend", dynlib: "Ws2_32.dll".}
|
stdcall, importc: "WSASend", dynlib: "Ws2_32.dll".}
|
||||||
|
|
||||||
|
proc get_osfhandle*(fd:TFileHandle): THandle {.
|
||||||
|
importc:"__get_osfhandle", header:"<io.h>".}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue