diff options
author | Federico Ceratto <federico.ceratto@gmail.com> | 2019-02-28 22:03:49 +0000 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-02-28 23:03:49 +0100 |
commit | 7d7cd69070c22b7e3034dcff97561a626468f09b (patch) | |
tree | 82e1d96ed867548fff2ac08a3882f0723d4aeaa1 | |
parent | 1102b8ac6e643c8f8428dd7db0994d26b0c65ea6 (diff) | |
download | Nim-7d7cd69070c22b7e3034dcff97561a626468f09b.tar.gz |
Improved posix module, added new posix_utils module (#10723)
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | lib/posix/posix.nim | 31 | ||||
-rw-r--r-- | lib/posix/posix_utils.nim | 101 | ||||
-rw-r--r-- | tools/kochdocs.nim | 1 |
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 = """ |