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
79
80
|
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 winlean, times
elif defined(posix):
import 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
when useWinUnicode:
var wSrc = newWideCString(src)
var wDst = newWideCString(dest)
if createSymbolicLinkW(wDst, wSrc, flag) == 0 or getLastError() != 0:
raiseOSError(osLastError(), $(src, dest))
else:
if createSymbolicLinkA(dest, src, 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):
result = symlinkPath
else:
result = newString(maxSymlinkLen)
var len = readlink(symlinkPath, result.cstring, maxSymlinkLen)
if len < 0:
raiseOSError(osLastError(), symlinkPath)
if len > maxSymlinkLen:
result = newString(len+1)
len = readlink(symlinkPath, result.cstring, len)
setLen(result, len)
|