summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFederico Ceratto <federico.ceratto@gmail.com>2019-02-28 22:03:49 +0000
committerAndreas Rumpf <rumpf_a@web.de>2019-02-28 23:03:49 +0100
commit7d7cd69070c22b7e3034dcff97561a626468f09b (patch)
tree82e1d96ed867548fff2ac08a3882f0723d4aeaa1
parent1102b8ac6e643c8f8428dd7db0994d26b0c65ea6 (diff)
downloadNim-7d7cd69070c22b7e3034dcff97561a626468f09b.tar.gz
Improved posix module, added new posix_utils module (#10723)
-rw-r--r--changelog.md1
-rw-r--r--lib/posix/posix.nim31
-rw-r--r--lib/posix/posix_utils.nim101
-rw-r--r--tools/kochdocs.nim1
4 files changed, 130 insertions, 4 deletions
diff --git a/changelog.md b/changelog.md
index 297a6c87b..86bc99ef7 100644
--- a/changelog.md
+++ b/changelog.md
@@ -128,6 +128,7 @@ proc enumToString*(enums: openArray[enum]): string =
 
 - Added `Rusage`, `getrusage`, `wait4` to posix interface.
 
+- Added the `posix_utils` module.
 
 
 ### Library changes
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index 800188b8f..1640f2902 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -196,6 +196,8 @@ when not (defined(linux) and defined(amd64)) and not defined(nintendoswitch):
 proc glob*(a1: cstring, a2: cint,
           a3: proc (x1: cstring, x2: cint): cint {.noconv.},
           a4: ptr Glob): cint {.importc, header: "<glob.h>".}
+  ## Filename globbing. Use `os.walkPattern() <os.html#glob_1>`_ and similar.
+
 proc globfree*(a1: ptr Glob) {.importc, header: "<glob.h>".}
 
 proc getgrgid*(a1: Gid): ptr Group {.importc, header: "<grp.h>".}
@@ -261,6 +263,8 @@ proc setpwent*() {.importc, header: "<pwd.h>".}
 
 proc uname*(a1: var Utsname): cint {.importc, header: "<sys/utsname.h>".}
 
+proc strerror*(errnum: cint): cstring {.importc, header: "<string.h>".}
+
 proc pthread_atfork*(a1, a2, a3: proc () {.noconv.}): cint {.
   importc, header: "<pthread.h>".}
 proc pthread_attr_destroy*(a1: ptr PthreadAttr): cint {.
@@ -459,11 +463,21 @@ proc fdatasync*(a1: cint): cint {.importc, header: "<unistd.h>".}
 proc fork*(): Pid {.importc, header: "<unistd.h>".}
 proc fpathconf*(a1, a2: cint): int {.importc, header: "<unistd.h>".}
 proc fsync*(a1: cint): cint {.importc, header: "<unistd.h>".}
+ ## synchronize a file's buffer cache to the storage device
+
 proc ftruncate*(a1: cint, a2: Off): cint {.importc, header: "<unistd.h>".}
 proc getcwd*(a1: cstring, a2: int): cstring {.importc, header: "<unistd.h>".}
-proc getegid*(): Gid {.importc, header: "<unistd.h>".}
+proc getuid*(): Uid {.importc, header: "<unistd.h>".}
+ ## returns the real user ID of the calling process
+
 proc geteuid*(): Uid {.importc, header: "<unistd.h>".}
+ ## returns the effective user ID of the calling process
+
 proc getgid*(): Gid {.importc, header: "<unistd.h>".}
+ ## returns the real group ID of the calling process
+
+proc getegid*(): Gid {.importc, header: "<unistd.h>".}
+ ## returns the effective group ID of the calling process
 
 proc getgroups*(a1: cint, a2: ptr array[0..255, Gid]): cint {.
   importc, header: "<unistd.h>".}
@@ -477,9 +491,14 @@ proc getopt*(a1: cint, a2: cstringArray, a3: cstring): cint {.
 proc getpgid*(a1: Pid): Pid {.importc, header: "<unistd.h>".}
 proc getpgrp*(): Pid {.importc, header: "<unistd.h>".}
 proc getpid*(): Pid {.importc, header: "<unistd.h>".}
+ ## returns  the process ID (PID) of the calling process
+
 proc getppid*(): Pid {.importc, header: "<unistd.h>".}
+ ## returns the process ID of the parent of the calling process
+
 proc getsid*(a1: Pid): Pid {.importc, header: "<unistd.h>".}
-proc getuid*(): Uid {.importc, header: "<unistd.h>".}
+ ## returns the session ID of the calling process
+
 proc getwd*(a1: cstring): cstring {.importc, header: "<unistd.h>".}
 proc isatty*(a1: cint): cint {.importc, header: "<unistd.h>".}
 proc lchown*(a1: cstring, a2: Uid, a3: Gid): cint {.importc, header: "<unistd.h>".}
@@ -560,6 +579,8 @@ proc fchmod*(a1: cint, a2: Mode): cint {.importc, header: "<sys/stat.h>".}
 proc fstat*(a1: cint, a2: var Stat): cint {.importc, header: "<sys/stat.h>".}
 proc lstat*(a1: cstring, a2: var Stat): cint {.importc, header: "<sys/stat.h>".}
 proc mkdir*(a1: cstring, a2: Mode): cint {.importc, header: "<sys/stat.h>".}
+  ## Use `os.createDir() <os.html#createDir>`_ and similar.
+
 proc mkfifo*(a1: cstring, a2: Mode): cint {.importc, header: "<sys/stat.h>".}
 proc mknod*(a1: cstring, a2: Mode, a3: Dev): cint {.
   importc, header: "<sys/stat.h>".}
@@ -598,6 +619,7 @@ proc mmap*(a1: pointer, a2: int, a3, a4, a5: cint, a6: Off): pointer {.
 proc mprotect*(a1: pointer, a2: int, a3: cint): cint {.
   importc, header: "<sys/mman.h>".}
 proc msync*(a1: pointer, a2: int, a3: cint): cint {.importc, header: "<sys/mman.h>".}
+
 proc munlock*(a1: pointer, a2: int): cint {.importc, header: "<sys/mman.h>".}
 proc munlockall*(): cint {.importc, header: "<sys/mman.h>".}
 proc munmap*(a1: pointer, a2: int): cint {.importc, header: "<sys/mman.h>".}
@@ -755,7 +777,6 @@ proc sched_setscheduler*(a1: Pid, a2: cint, a3: var Sched_param): cint {.
   importc, header: "<sched.h>".}
 proc sched_yield*(): cint {.importc, header: "<sched.h>".}
 
-proc strerror*(errnum: cint): cstring {.importc, header: "<string.h>".}
 proc hstrerror*(herrnum: cint): cstring {.importc:"(char *)$1", header: "<netdb.h>".}
 
 proc FD_CLR*(a1: cint, a2: var TFdSet) {.importc, header: "<sys/select.h>".}
@@ -990,11 +1011,13 @@ proc realpath*(name, resolved: cstring): cstring {.
   importc: "realpath", header: "<stdlib.h>".}
 
 proc mkstemp*(tmpl: cstring): cint {.importc, header: "<stdlib.h>".}
-  ## Create a temporary file.
+  ## Creates a unique temporary file.
   ##
   ## **Warning**: The `tmpl` argument is written to by `mkstemp` and thus
   ## can't be a string literal. If in doubt copy the string before passing it.
 
+proc mkdtemp*(tmpl: cstring): pointer {.importc, header: "<stdlib.h>".}
+
 proc utimes*(path: cstring, times: ptr array[2, Timeval]): int {.
   importc: "utimes", header: "<sys/time.h>".}
   ## Sets file access and modification times.
diff --git a/lib/posix/posix_utils.nim b/lib/posix/posix_utils.nim
new file mode 100644
index 000000000..ea6ef60f4
--- /dev/null
+++ b/lib/posix/posix_utils.nim
@@ -0,0 +1,101 @@
+#
+#            Nim's Runtime Library
+#    (c) Copyright 2019 Federico Ceratto and other Nim contributors
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## A set of helpers for the POSIX module.
+## Raw interfaces are in the other posix*.nim files.
+
+# Where possible, contribute OS-independent procs in `os <os.html>`_ instead.
+
+{.deadCodeElim: on.}  # dce option deprecated
+
+import posix
+
+type Uname* = object
+  sysname*, nodename*, release*, version*, machine*: string
+
+template charArrayToString(input: typed): string =
+  $cstring(addr input)
+
+proc uname*(): Uname =
+  ## Provides system information in a `Uname` struct with sysname, nodename,
+  ## release, version and machine attributes.
+
+  when defined(posix):
+    runnableExamples:
+      echo uname().nodename, uname().release, uname().version
+      doAssert uname().sysname.len != 0
+
+  var u: Utsname
+  if uname(u) != 0:
+    raise newException(OSError, $strerror(errno))
+
+  result.sysname = charArrayToString u.sysname
+  result.nodename = charArrayToString u.nodename
+  result.release = charArrayToString u.release
+  result.version = charArrayToString u.version
+  result.machine = charArrayToString u.machine
+
+proc fsync*(fd: int) =
+ ## synchronize a file's buffer cache to the storage device
+ if fsync(fd.cint) != 0:
+    raise newException(OSError, $strerror(errno))
+
+proc stat*(path: string): Stat =
+  ## Returns file status in a `Stat` structure
+  if stat(path.cstring, result) != 0:
+    raise newException(OSError, $strerror(errno))
+
+proc memoryLock*(a1: pointer, a2: int) =
+  ## Locks pages starting from a1 for a1 bytes and prevent them from being swapped.
+  if mlock(a1, a2) != 0:
+    raise newException(OSError, $strerror(errno))
+
+proc memoryLockAll*(flags: int) =
+  ## Locks all memory for the running process to prevent swapping.
+  ##
+  ## example::
+  ##
+  ##   memoryLockAll(MCL_CURRENT or MCL_FUTURE)
+  if mlockall(flags.cint) != 0:
+    raise newException(OSError, $strerror(errno))
+
+proc memoryUnlock*(a1: pointer, a2: int) =
+  ## Unlock pages starting from a1 for a1 bytes and allow them to be swapped.
+  if munlock(a1, a2) != 0:
+    raise newException(OSError, $strerror(errno))
+
+proc memoryUnlockAll*() =
+  ## Unlocks all memory for the running process to allow swapping.
+  if munlockall() != 0:
+    raise newException(OSError, $strerror(errno))
+
+proc sendSignal*(pid: Pid, signal: int) =
+  ## Sends a signal to a running process by calling `kill`.
+  ## Raise exception in case of failure e.g. process not running.
+  if kill(pid, signal.cint) != 0:
+    raise newException(OSError, $strerror(errno))
+
+proc mkstemp*(prefix: string): (string, File) =
+  ## Creates a unique temporary file from a prefix string. Adds a six chars suffix.
+  ## The file is created with perms 0600.
+  ## Returs the filename and a file opened in r/w mode.
+  var tmpl = cstring(prefix & "XXXXXX")
+  let fd = mkstemp(tmpl)
+  var f: File
+  if open(f, fd, fmReadWrite):
+    return ($tmpl, f)
+  raise newException(OSError, $strerror(errno))
+
+proc mkdtemp*(prefix: string): string =
+  ## Creates a unique temporary directory from a prefix string. Adds a six chars suffix.
+  ## The directory is created with permissions 0700. Returns the directory name.
+  var tmpl = cstring(prefix & "XXXXXX")
+  if mkdtemp(tmpl) == nil:
+    raise newException(OSError, $strerror(errno))
+  return $tmpl
+
diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim
index e1b5c4271..4adce2b69 100644
--- a/tools/kochdocs.nim
+++ b/tools/kochdocs.nim
@@ -249,6 +249,7 @@ lib/pure/bitops.nim
 lib/pure/nimtracker.nim
 lib/pure/punycode.nim
 lib/pure/volatile.nim
+lib/posix/posix_utils.nim
 """.splitWhitespace()
 
   doc0 = """