summary refs log tree commit diff stats
path: root/lib/std/private/ossymlinks.nim
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2022-10-20 13:58:29 +0800
committerGitHub <noreply@github.com>2022-10-20 07:58:29 +0200
commitf6a002c8a582d83e9d7b51b945d26cf428699ad9 (patch)
treeb89bfe169e1707a6c66fa24c8e880bb8a2f3fc81 /lib/std/private/ossymlinks.nim
parentea5dcdbe8f9cd62e06f300c660cb31667b95b26c (diff)
downloadNim-f6a002c8a582d83e9d7b51b945d26cf428699ad9.tar.gz
[std/os] split and re-export (#20593)
* [std/os] split and export
* move to private modules
* fixes docs and tests

Co-authored-by: xflywind <43030857+xflywind@users.noreply.github.com>
Diffstat (limited to 'lib/std/private/ossymlinks.nim')
-rw-r--r--lib/std/private/ossymlinks.nim79
1 files changed, 79 insertions, 0 deletions
diff --git a/lib/std/private/ossymlinks.nim b/lib/std/private/ossymlinks.nim
new file mode 100644
index 000000000..cb6287bde
--- /dev/null
+++ b/lib/std/private/ossymlinks.nim
@@ -0,0 +1,79 @@
+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.}
+
+
+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)