1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
include system/inclrtl
import std/oserrors
import oscommon
export symlinkExists
when defined(nimPreviewSlimSystem):
import std/[syncio, assertions, widestrs]
when weirdTarget:
discard
elif defined(windows):
import std/[winlean, times]
elif defined(posix):
import std/posix
else:
{.error: "OS module not ported to your operating system!".}
when weirdTarget:
{.pragma: noWeirdTarget, error: "this proc is not available on the NimScript/js target".}
else:
{.pragma: noWeirdTarget.}
when defined(nimscript):
# for procs already defined in scriptconfig.nim
template noNimJs(body): untyped = discard
elif defined(js):
{.pragma: noNimJs, error: "this proc is not available on the js target".}
else:
{.pragma: noNimJs.}
## .. importdoc:: os.nim
proc createSymlink*(src, dest: string) {.noWeirdTarget.} =
## Create a symbolic link at `dest` which points to the item specified
## by `src`. On most operating systems, will fail if a link already exists.
##
## .. warning:: Some OS's (such as Microsoft Windows) restrict the creation
## of symlinks to root users (administrators) or users with developer mode enabled.
##
## See also:
## * `createHardlink proc`_
## * `expandSymlink proc`_
when defined(windows):
const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 2
# allows anyone with developer mode on to create a link
let flag = dirExists(src).int32 or SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
var wSrc = newWideCString(src)
var wDst = newWideCString(dest)
if createSymbolicLinkW(wDst, wSrc, flag) == 0 or getLastError() != 0:
raiseOSError(osLastError(), $(src, dest))
else:
if symlink(src, dest) != 0:
raiseOSError(osLastError(), $(src, dest))
proc expandSymlink*(symlinkPath: string): string {.noWeirdTarget.} =
## Returns a string representing the path to which the symbolic link points.
##
## On Windows this is a noop, `symlinkPath` is simply returned.
##
## See also:
## * `createSymlink proc`_
when defined(windows) or defined(nintendoswitch):
result = symlinkPath
else:
var bufLen = 1024
while true:
result = newString(bufLen)
let len = readlink(symlinkPath.cstring, result.cstring, bufLen)
if len < 0:
raiseOSError(osLastError(), symlinkPath)
if len < bufLen:
result.setLen(len)
break
bufLen = bufLen shl 1
|