Skip to content

Commit

Permalink
refs nim-lang#8391 std/os now shows runtime context for raiseOSError …
Browse files Browse the repository at this point in the history
…exceptions
  • Loading branch information
timotheecour committed Jan 29, 2020
1 parent 3f6af9b commit 200da61
Showing 1 changed file with 46 additions and 47 deletions.
93 changes: 46 additions & 47 deletions lib/pure/os.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1169,7 +1169,7 @@ proc findExe*(exe: string, followSymlinks: bool = true;
var r = newString(256)
var len = readlink(x, r, 256)
if len < 0:
raiseOSError(osLastError())
raiseOSError(osLastError(), exe)
if len > 256:
r = newString(len+1)
len = readlink(x, r, len)
Expand All @@ -1196,12 +1196,12 @@ proc getLastModificationTime*(file: string): times.Time {.rtl, extern: "nos$1",
## * `fileNewer proc <#fileNewer,string,string>`_
when defined(posix):
var res: Stat
if stat(file, res) < 0'i32: raiseOSError(osLastError())
if stat(file, res) < 0'i32: raiseOSError(osLastError(), file)
result = res.st_mtim.toTime
else:
var f: WIN32_FIND_DATA
var h = findFirstFile(file, f)
if h == -1'i32: raiseOSError(osLastError())
if h == -1'i32: raiseOSError(osLastError(), file)
result = fromWinTime(rdFileTime(f.ftLastWriteTime))
findClose(h)

Expand All @@ -1214,12 +1214,12 @@ proc getLastAccessTime*(file: string): times.Time {.rtl, extern: "nos$1", noNimS
## * `fileNewer proc <#fileNewer,string,string>`_
when defined(posix):
var res: Stat
if stat(file, res) < 0'i32: raiseOSError(osLastError())
if stat(file, res) < 0'i32: raiseOSError(osLastError(), file)
result = res.st_atim.toTime
else:
var f: WIN32_FIND_DATA
var h = findFirstFile(file, f)
if h == -1'i32: raiseOSError(osLastError())
if h == -1'i32: raiseOSError(osLastError(), file)
result = fromWinTime(rdFileTime(f.ftLastAccessTime))
findClose(h)

Expand All @@ -1236,12 +1236,12 @@ proc getCreationTime*(file: string): times.Time {.rtl, extern: "nos$1", noNimScr
## * `fileNewer proc <#fileNewer,string,string>`_
when defined(posix):
var res: Stat
if stat(file, res) < 0'i32: raiseOSError(osLastError())
if stat(file, res) < 0'i32: raiseOSError(osLastError(), file)
result = res.st_ctim.toTime
else:
var f: WIN32_FIND_DATA
var h = findFirstFile(file, f)
if h == -1'i32: raiseOSError(osLastError())
if h == -1'i32: raiseOSError(osLastError(), file)
result = fromWinTime(rdFileTime(f.ftCreationTime))
findClose(h)

Expand Down Expand Up @@ -1470,11 +1470,11 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1",
discard closeHandle(f1)
discard closeHandle(f2)

if not success: raiseOSError(lastErr)
if not success: raiseOSError(lastErr, $(path1, path2))
else:
var a, b: Stat
if stat(path1, a) < 0'i32 or stat(path2, b) < 0'i32:
raiseOSError(osLastError())
raiseOSError(osLastError(), $(path1, path2))
else:
result = a.st_dev == b.st_dev and a.st_ino == b.st_ino

Expand Down Expand Up @@ -1542,7 +1542,7 @@ proc getFilePermissions*(filename: string): set[FilePermission] {.
## * `FilePermission enum <#FilePermission>`_
when defined(posix):
var a: Stat
if stat(filename, a) < 0'i32: raiseOSError(osLastError())
if stat(filename, a) < 0'i32: raiseOSError(osLastError(), filename)
result = {}
if (a.st_mode and S_IRUSR.Mode) != 0.Mode: result.incl(fpUserRead)
if (a.st_mode and S_IWUSR.Mode) != 0.Mode: result.incl(fpUserWrite)
Expand All @@ -1560,7 +1560,7 @@ proc getFilePermissions*(filename: string): set[FilePermission] {.
wrapUnary(res, getFileAttributesW, filename)
else:
var res = getFileAttributesA(filename)
if res == -1'i32: raiseOSError(osLastError())
if res == -1'i32: raiseOSError(osLastError(), filename)
if (res and FILE_ATTRIBUTE_READONLY) != 0'i32:
result = {fpUserExec, fpUserRead, fpGroupExec, fpGroupRead,
fpOthersExec, fpOthersRead}
Expand Down Expand Up @@ -1592,13 +1592,13 @@ proc setFilePermissions*(filename: string, permissions: set[FilePermission]) {.
if fpOthersWrite in permissions: p = p or S_IWOTH.Mode
if fpOthersExec in permissions: p = p or S_IXOTH.Mode

if chmod(filename, cast[Mode](p)) != 0: raiseOSError(osLastError())
if chmod(filename, cast[Mode](p)) != 0: raiseOSError(osLastError(), $(filename, permissions))
else:
when useWinUnicode:
wrapUnary(res, getFileAttributesW, filename)
else:
var res = getFileAttributesA(filename)
if res == -1'i32: raiseOSError(osLastError())
if res == -1'i32: raiseOSError(osLastError(), filename)
if fpUserWrite in permissions:
res = res and not FILE_ATTRIBUTE_READONLY
else:
Expand All @@ -1607,7 +1607,7 @@ proc setFilePermissions*(filename: string, permissions: set[FilePermission]) {.
wrapBinary(res2, setFileAttributesW, filename, res)
else:
var res2 = setFileAttributesA(filename, res)
if res2 == - 1'i32: raiseOSError(osLastError())
if res2 == - 1'i32: raiseOSError(osLastError(), $(filename, permissions))

proc copyFile*(source, dest: string) {.rtl, extern: "nos$1",
tags: [ReadIOEffect, WriteIOEffect], noNimScript.} =
Expand Down Expand Up @@ -1640,9 +1640,9 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1",
when useWinUnicode:
let s = newWideCString(source)
let d = newWideCString(dest)
if copyFileW(s, d, 0'i32) == 0'i32: raiseOSError(osLastError())
if copyFileW(s, d, 0'i32) == 0'i32: raiseOSError(osLastError(), $(source, dest))
else:
if copyFileA(source, dest, 0'i32) == 0'i32: raiseOSError(osLastError())
if copyFileA(source, dest, 0'i32) == 0'i32: raiseOSError(osLastError(), $(source, dest))
else:
# generic version of copyFile which works for any platform:
const bufSize = 8000 # better for memory manager
Expand All @@ -1660,7 +1660,7 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1",
dealloc(buf)
close(s)
close(d)
raiseOSError(osLastError())
raiseOSError(osLastError(), dest)
if bytesread != bufSize: break
dealloc(buf)
close(s)
Expand Down Expand Up @@ -1733,10 +1733,7 @@ proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [WriteDirEffect], n
## * `tryRemoveFile proc <#tryRemoveFile,string>`_
## * `moveFile proc <#moveFile,string,string>`_
if not tryRemoveFile(file):
when defined(Windows):
raiseOSError(osLastError())
else:
raiseOSError(osLastError(), $strerror(errno))
raiseOSError(osLastError(), file)

proc tryMoveFSObject(source, dest: string): bool {.noNimScript.} =
## Moves a file or directory from `source` to `dest`.
Expand All @@ -1748,16 +1745,17 @@ proc tryMoveFSObject(source, dest: string): bool {.noNimScript.} =
when useWinUnicode:
let s = newWideCString(source)
let d = newWideCString(dest)
if moveFileExW(s, d, MOVEFILE_COPY_ALLOWED) == 0'i32: raiseOSError(osLastError())
if moveFileExW(s, d, MOVEFILE_COPY_ALLOWED) == 0'i32: raiseOSError(osLastError(), $(source, dest))
else:
if moveFileExA(source, dest, MOVEFILE_COPY_ALLOWED) == 0'i32: raiseOSError(osLastError())
if moveFileExA(source, dest, MOVEFILE_COPY_ALLOWED) == 0'i32: raiseOSError(osLastError(), $(source, dest))
else:
if c_rename(source, dest) != 0'i32:
let err = osLastError()
if err == EXDEV.OSErrorCode:
return false
else:
raiseOSError(err, $strerror(errno))
# see whether `strerror(errno)` is redundant with what raiseOSError already shows
raiseOSError(err, $(source, dest, strerror(errno)))
return true

proc moveFile*(source, dest: string) {.rtl, extern: "nos$1",
Expand Down Expand Up @@ -1927,7 +1925,7 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
while true:
var L = getFullPathNameW(newWideCString(filename), bufsize, res, unused)
if L == 0'i32:
raiseOSError(osLastError())
raiseOSError(osLastError(), filename)
elif L > bufsize:
res = newWideCString("", L)
bufsize = L
Expand All @@ -1940,7 +1938,7 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
while true:
var L = getFullPathNameA(filename, bufsize, result, unused)
if L == 0'i32:
raiseOSError(osLastError())
raiseOSError(osLastError(), filename)
elif L > bufsize:
result = newString(L)
bufsize = L
Expand All @@ -1952,13 +1950,14 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
for x in walkFiles(result):
result = x
if not existsFile(result) and not existsDir(result):
# consider using: `raiseOSError(osLastError(), result)`
raise newException(OSError, "file '" & result & "' does not exist")
else:
# according to Posix we don't need to allocate space for result pathname.
# But we need to free return value with free(3).
var r = realpath(filename, nil)
if r.isNil:
raiseOSError(osLastError())
raiseOSError(osLastError(), filename)
else:
result = $r
c_free(cast[pointer](r))
Expand Down Expand Up @@ -2145,9 +2144,9 @@ proc rawRemoveDir(dir: string) {.noNimScript.} =
let lastError = osLastError()
if res == 0'i32 and lastError.int32 != 3'i32 and
lastError.int32 != 18'i32 and lastError.int32 != 2'i32:
raiseOSError(lastError)
raiseOSError(lastError, dir)
else:
if rmdir(dir) != 0'i32 and errno != ENOENT: raiseOSError(osLastError())
if rmdir(dir) != 0'i32 and errno != ENOENT: raiseOSError(osLastError(), dir)

proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [
WriteDirEffect, ReadDirEffect], benign, noNimScript.} =
Expand Down Expand Up @@ -2336,13 +2335,13 @@ proc createSymlink*(src, dest: string) {.noNimScript.} =
var wSrc = newWideCString(src)
var wDst = newWideCString(dest)
if createSymbolicLinkW(wDst, wSrc, flag) == 0 or getLastError() != 0:
raiseOSError(osLastError())
raiseOSError(osLastError(), $(src, dest))
else:
if createSymbolicLinkA(dest, src, flag) == 0 or getLastError() != 0:
raiseOSError(osLastError())
raiseOSError(osLastError(), $(src, dest))
else:
if symlink(src, dest) != 0:
raiseOSError(osLastError())
raiseOSError(osLastError(), $(src, dest))

proc createHardlink*(src, dest: string) {.noNimScript.} =
## Create a hard link at `dest` which points to the item specified
Expand All @@ -2358,13 +2357,13 @@ proc createHardlink*(src, dest: string) {.noNimScript.} =
var wSrc = newWideCString(src)
var wDst = newWideCString(dest)
if createHardLinkW(wDst, wSrc, nil) == 0:
raiseOSError(osLastError())
raiseOSError(osLastError(), $(src, dest))
else:
if createHardLinkA(dest, src, nil) == 0:
raiseOSError(osLastError())
raiseOSError(osLastError(), $(src, dest))
else:
if link(src, dest) != 0:
raiseOSError(osLastError())
raiseOSError(osLastError(), $(src, dest))

proc copyFileWithPermissions*(source, dest: string,
ignorePermissionErrors = true) {.noNimScript.} =
Expand Down Expand Up @@ -2473,7 +2472,7 @@ proc expandSymlink*(symlinkPath: string): string {.noNimScript.} =
result = newString(256)
var len = readlink(symlinkPath, result, 256)
if len < 0:
raiseOSError(osLastError())
raiseOSError(osLastError(), symlinkPath)
if len > 256:
result = newString(len+1)
len = readlink(symlinkPath, result, len)
Expand Down Expand Up @@ -2942,15 +2941,15 @@ proc getFileSize*(file: string): BiggestInt {.rtl, extern: "nos$1",
when defined(windows):
var a: WIN32_FIND_DATA
var resA = findFirstFile(file, a)
if resA == -1: raiseOSError(osLastError())
if resA == -1: raiseOSError(osLastError(), file)
result = rdFileSize(a)
findClose(resA)
else:
var f: File
if open(f, file):
result = getFileSize(f)
close(f)
else: raiseOSError(osLastError())
else: raiseOSError(osLastError(), file)

when defined(Windows) or weirdTarget:
type
Expand Down Expand Up @@ -3061,12 +3060,12 @@ proc getFileInfo*(handle: FileHandle): FileInfo {.noNimScript.} =
# To transform the C file descriptor to a native file handle.
var realHandle = get_osfhandle(handle)
if getFileInformationByHandle(realHandle, addr rawInfo) == 0:
raiseOSError(osLastError())
raiseOSError(osLastError(), $handle)
rawToFormalFileInfo(rawInfo, "", result)
else:
var rawInfo: Stat
if fstat(handle, rawInfo) < 0'i32:
raiseOSError(osLastError())
raiseOSError(osLastError(), $handle)
rawToFormalFileInfo(rawInfo, "", result)

proc getFileInfo*(file: File): FileInfo {.noNimScript.} =
Expand Down Expand Up @@ -3102,19 +3101,19 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo {.noNimScript.}
handle = openHandle(path, followSymlink)
rawInfo: BY_HANDLE_FILE_INFORMATION
if handle == INVALID_HANDLE_VALUE:
raiseOSError(osLastError())
raiseOSError(osLastError(), path)
if getFileInformationByHandle(handle, addr rawInfo) == 0:
raiseOSError(osLastError())
raiseOSError(osLastError(), path)
rawToFormalFileInfo(rawInfo, path, result)
discard closeHandle(handle)
else:
var rawInfo: Stat
if followSymlink:
if stat(path, rawInfo) < 0'i32:
raiseOSError(osLastError())
raiseOSError(osLastError(), path)
else:
if lstat(path, rawInfo) < 0'i32:
raiseOSError(osLastError())
raiseOSError(osLastError(), path)
rawToFormalFileInfo(rawInfo, path, result)

proc isHidden*(path: string): bool {.noNimScript.} =
Expand Down Expand Up @@ -3167,14 +3166,14 @@ proc setLastModificationTime*(file: string, t: times.Time) {.noNimScript.} =
let micro = convert(Nanoseconds, Microseconds, t.nanosecond)
var timevals = [Timeval(tv_sec: unixt, tv_usec: micro),
Timeval(tv_sec: unixt, tv_usec: micro)] # [last access, last modification]
if utimes(file, timevals.addr) != 0: raiseOSError(osLastError())
if utimes(file, timevals.addr) != 0: raiseOSError(osLastError(), file)
else:
let h = openHandle(path = file, writeAccess = true)
if h == INVALID_HANDLE_VALUE: raiseOSError(osLastError())
if h == INVALID_HANDLE_VALUE: raiseOSError(osLastError(), file)
var ft = t.toWinTime.toFILETIME
let res = setFileTime(h, nil, nil, ft.addr)
discard h.closeHandle
if res == 0'i32: raiseOSError(osLastError())
if res == 0'i32: raiseOSError(osLastError(), file)


when isMainModule:
Expand Down

0 comments on commit 200da61

Please sign in to comment.