mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 01:44:37 +00:00
130 lines
4.6 KiB
Nim
130 lines
4.6 KiB
Nim
#
|
|
# 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.
|
|
|
|
import posix, parsecfg, os
|
|
import std/private/since
|
|
|
|
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, suffix=""): (string, File) =
|
|
## Creates a unique temporary file from a prefix string. A six-character string
|
|
## will be added. If suffix is provided it will be added to the string
|
|
## The file is created with perms 0600.
|
|
## Returns the filename and a file opened in r/w mode.
|
|
var tmpl = cstring(prefix & "XXXXXX" & suffix)
|
|
let fd =
|
|
if len(suffix)==0:
|
|
when declared(mkostemp):
|
|
mkostemp(tmpl, O_CLOEXEC)
|
|
else:
|
|
mkstemp(tmpl)
|
|
else:
|
|
when declared(mkostemps):
|
|
mkostemps(tmpl, cint(len(suffix)), O_CLOEXEC)
|
|
else:
|
|
mkstemps(tmpl, cint(len(suffix)))
|
|
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
|
|
|
|
proc osReleaseFile*(): Config {.since: (1, 5).} =
|
|
## Gets system identification from `os-release` file and returns it as a `parsecfg.Config`.
|
|
## You also need to import the `parsecfg` module to gain access to this object.
|
|
## The `os-release` file is an official Freedesktop.org open standard.
|
|
## Available in Linux and BSD distributions, except Android and Android-based Linux.
|
|
## `os-release` file is not available on Windows and OS X by design.
|
|
## * https://www.freedesktop.org/software/systemd/man/os-release.html
|
|
runnableExamples:
|
|
import std/parsecfg
|
|
when defined(linux):
|
|
let data = osReleaseFile()
|
|
echo "OS name: ", data.getSectionValue("", "NAME") ## the data is up to each distro.
|
|
|
|
# We do not use a {.strdefine.} because Standard says it *must* be that path.
|
|
for osReleaseFile in ["/etc/os-release", "/usr/lib/os-release"]:
|
|
if fileExists(osReleaseFile):
|
|
return loadConfig(osReleaseFile)
|
|
raise newException(IOError, "File not found: /etc/os-release, /usr/lib/os-release")
|