Improved posix module, added new posix_utils module (#10723)
This commit is contained in:
parent
1102b8ac6e
commit
7d7cd69070
4 changed files with 130 additions and 4 deletions
|
|
@ -128,6 +128,7 @@ proc enumToString*(enums: openArray[enum]): string =
|
||||||
|
|
||||||
- Added `Rusage`, `getrusage`, `wait4` to posix interface.
|
- Added `Rusage`, `getrusage`, `wait4` to posix interface.
|
||||||
|
|
||||||
|
- Added the `posix_utils` module.
|
||||||
|
|
||||||
|
|
||||||
### Library changes
|
### Library changes
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,8 @@ when not (defined(linux) and defined(amd64)) and not defined(nintendoswitch):
|
||||||
proc glob*(a1: cstring, a2: cint,
|
proc glob*(a1: cstring, a2: cint,
|
||||||
a3: proc (x1: cstring, x2: cint): cint {.noconv.},
|
a3: proc (x1: cstring, x2: cint): cint {.noconv.},
|
||||||
a4: ptr Glob): cint {.importc, header: "<glob.h>".}
|
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 globfree*(a1: ptr Glob) {.importc, header: "<glob.h>".}
|
||||||
|
|
||||||
proc getgrgid*(a1: Gid): ptr Group {.importc, header: "<grp.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 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 {.
|
proc pthread_atfork*(a1, a2, a3: proc () {.noconv.}): cint {.
|
||||||
importc, header: "<pthread.h>".}
|
importc, header: "<pthread.h>".}
|
||||||
proc pthread_attr_destroy*(a1: ptr PthreadAttr): cint {.
|
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 fork*(): Pid {.importc, header: "<unistd.h>".}
|
||||||
proc fpathconf*(a1, a2: cint): int {.importc, header: "<unistd.h>".}
|
proc fpathconf*(a1, a2: cint): int {.importc, header: "<unistd.h>".}
|
||||||
proc fsync*(a1: cint): cint {.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 ftruncate*(a1: cint, a2: Off): cint {.importc, header: "<unistd.h>".}
|
||||||
proc getcwd*(a1: cstring, a2: int): cstring {.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>".}
|
proc geteuid*(): Uid {.importc, header: "<unistd.h>".}
|
||||||
|
## returns the effective user ID of the calling process
|
||||||
|
|
||||||
proc getgid*(): Gid {.importc, header: "<unistd.h>".}
|
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 {.
|
proc getgroups*(a1: cint, a2: ptr array[0..255, Gid]): cint {.
|
||||||
importc, header: "<unistd.h>".}
|
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 getpgid*(a1: Pid): Pid {.importc, header: "<unistd.h>".}
|
||||||
proc getpgrp*(): Pid {.importc, header: "<unistd.h>".}
|
proc getpgrp*(): Pid {.importc, header: "<unistd.h>".}
|
||||||
proc getpid*(): 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>".}
|
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 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 getwd*(a1: cstring): cstring {.importc, header: "<unistd.h>".}
|
||||||
proc isatty*(a1: cint): cint {.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>".}
|
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 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 lstat*(a1: cstring, a2: var Stat): cint {.importc, header: "<sys/stat.h>".}
|
||||||
proc mkdir*(a1: cstring, a2: Mode): 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 mkfifo*(a1: cstring, a2: Mode): cint {.importc, header: "<sys/stat.h>".}
|
||||||
proc mknod*(a1: cstring, a2: Mode, a3: Dev): cint {.
|
proc mknod*(a1: cstring, a2: Mode, a3: Dev): cint {.
|
||||||
importc, header: "<sys/stat.h>".}
|
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 {.
|
proc mprotect*(a1: pointer, a2: int, a3: cint): cint {.
|
||||||
importc, header: "<sys/mman.h>".}
|
importc, header: "<sys/mman.h>".}
|
||||||
proc msync*(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 munlock*(a1: pointer, a2: int): cint {.importc, header: "<sys/mman.h>".}
|
||||||
proc munlockall*(): 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>".}
|
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>".}
|
importc, header: "<sched.h>".}
|
||||||
proc sched_yield*(): 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 hstrerror*(herrnum: cint): cstring {.importc:"(char *)$1", header: "<netdb.h>".}
|
||||||
|
|
||||||
proc FD_CLR*(a1: cint, a2: var TFdSet) {.importc, header: "<sys/select.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>".}
|
importc: "realpath", header: "<stdlib.h>".}
|
||||||
|
|
||||||
proc mkstemp*(tmpl: cstring): cint {.importc, 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
|
## **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.
|
## 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 {.
|
proc utimes*(path: cstring, times: ptr array[2, Timeval]): int {.
|
||||||
importc: "utimes", header: "<sys/time.h>".}
|
importc: "utimes", header: "<sys/time.h>".}
|
||||||
## Sets file access and modification times.
|
## Sets file access and modification times.
|
||||||
|
|
|
||||||
101
lib/posix/posix_utils.nim
Normal file
101
lib/posix/posix_utils.nim
Normal file
|
|
@ -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
|
||||||
|
|
||||||
|
|
@ -249,6 +249,7 @@ lib/pure/bitops.nim
|
||||||
lib/pure/nimtracker.nim
|
lib/pure/nimtracker.nim
|
||||||
lib/pure/punycode.nim
|
lib/pure/punycode.nim
|
||||||
lib/pure/volatile.nim
|
lib/pure/volatile.nim
|
||||||
|
lib/posix/posix_utils.nim
|
||||||
""".splitWhitespace()
|
""".splitWhitespace()
|
||||||
|
|
||||||
doc0 = """
|
doc0 = """
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue