- Notifications
You must be signed in to change notification settings - Fork 1.5k
/
Copy pathposix_utils.nim
133 lines (112 loc) · 4.61 KB
/
posix_utils.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#
# 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 std/[posix, parsecfg, os]
import std/private/since
whendefined(nimPreviewSlimSystem):
import std/syncio
typeUname*=object
sysname*, nodename*, release*, version*, machine*: string
templatecharArrayToString(input: typed): string=
$cast[cstring](addr input)
procuname*(): Uname=
## Provides system information in a `Uname` struct with sysname, nodename,
## release, version and machine attributes.
whendefined(posix):
runnableExamples:
echouname().nodename, uname().release, uname().version
doAssertuname().sysname.len !=0
var u: Utsname
ifuname(u) !=0:
raiseOSError(OSErrorCode(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
procfsync*(fd: int) =
## synchronize a file's buffer cache to the storage device
iffsync(fd.cint) !=0:
raiseOSError(OSErrorCode(errno))
procstat*(path: string): Stat=
## Returns file status in a `Stat` structure
ifstat(path.cstring, result) !=0:
raiseOSError(OSErrorCode(errno))
procmemoryLock*(a1: pointer, a2: int) =
## Locks pages starting from a1 for a1 bytes and prevent them from being swapped.
ifmlock(a1, a2) !=0:
raiseOSError(OSErrorCode(errno))
procmemoryLockAll*(flags: int) =
## Locks all memory for the running process to prevent swapping.
##
## example:
## ```nim
## memoryLockAll(MCL_CURRENT or MCL_FUTURE)
## ```
ifmlockall(flags.cint) !=0:
raiseOSError(OSErrorCode(errno))
procmemoryUnlock*(a1: pointer, a2: int) =
## Unlock pages starting from a1 for a1 bytes and allow them to be swapped.
ifmunlock(a1, a2) !=0:
raiseOSError(OSErrorCode(errno))
procmemoryUnlockAll*() =
## Unlocks all memory for the running process to allow swapping.
ifmunlockall() !=0:
raiseOSError(OSErrorCode(errno))
procsendSignal*(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.
ifkill(pid, signal.cint) !=0:
raiseOSError(OSErrorCode(errno))
procmkstemp*(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 =
iflen(suffix) ==0:
whendeclared(mkostemp):
mkostemp(tmpl, O_CLOEXEC)
else:
mkstemp(tmpl)
else:
whendeclared(mkostemps):
mkostemps(tmpl, cint(len(suffix)), O_CLOEXEC)
else:
mkstemps(tmpl, cint(len(suffix)))
var f: File
ifopen(f, fd, fmReadWrite):
return ($tmpl, f)
raiseOSError(OSErrorCode(errno))
procmkdtemp*(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")
ifmkdtemp(tmpl) ==nil:
raiseOSError(OSErrorCode(errno))
return$tmpl
procosReleaseFile*(): 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
whendefined(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"]:
iffileExists(osReleaseFile):
returnloadConfig(osReleaseFile)
raisenewException(IOError, "File not found: /etc/os-release, /usr/lib/os-release")