diff options
Diffstat (limited to 'lib/posix/posix.nim')
-rw-r--r-- | lib/posix/posix.nim | 329 |
1 files changed, 209 insertions, 120 deletions
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index 70ba53a2e..fbe945df3 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -27,17 +27,19 @@ ## the \`identifier\` notation is used. ## ## This library relies on the header files of your C compiler. The -## resulting C code will just ``#include <XYZ.h>`` and *not* define the +## resulting C code will just `#include <XYZ.h>` and *not* define the ## symbols declared here. # Dead code elimination ensures that we don't accidentally generate #includes # for files that might not exist on a specific platform! The user will get an # error only if they actually try to use the missing declaration -{.deadCodeElim: on.} # dce option deprecated when defined(nimHasStyleChecks): {.push styleChecks: off.} +when defined(nimPreviewSlimSystem): + import std/syncio + # TODO these constants don't seem to be fetched from a header file for unknown # platforms - where do they come from and why are they here? when false: @@ -89,10 +91,10 @@ const type Sighandler = proc (a: cint) {.noconv.} const StatHasNanoseconds* = defined(linux) or defined(freebsd) or - defined(osx) or defined(openbsd) or defined(dragonfly) ## \ + defined(osx) or defined(openbsd) or defined(dragonfly) or defined(haiku) ## \ ## Boolean flag that indicates if the system supports nanosecond time - ## resolution in the fields of ``Stat``. Note that the nanosecond based fields - ## (``Stat.st_atim``, ``Stat.st_mtim`` and ``Stat.st_ctim``) can be accessed + ## resolution in the fields of `Stat`. Note that the nanosecond based fields + ## (`Stat.st_atim`, `Stat.st_mtim` and `Stat.st_ctim`) can be accessed ## without checking this flag, because this module defines fallback procs ## when they are not available. @@ -106,6 +108,8 @@ elif (defined(macos) or defined(macosx) or defined(bsd)) and defined(cpu64): include posix_macos_amd64 elif defined(nintendoswitch): include posix_nintendoswitch +elif defined(haiku): + include posix_haiku else: include posix_other @@ -150,11 +154,13 @@ proc htons*(a1: uint16): uint16 {.importc, header: "<arpa/inet.h>".} proc ntohl*(a1: uint32): uint32 {.importc, header: "<arpa/inet.h>".} proc ntohs*(a1: uint16): uint16 {.importc, header: "<arpa/inet.h>".} -proc inet_addr*(a1: cstring): InAddrT {.importc, header: "<arpa/inet.h>".} -proc inet_ntoa*(a1: InAddr): cstring {.importc, header: "<arpa/inet.h>".} -proc inet_ntop*(a1: cint, a2: pointer, a3: cstring, a4: int32): cstring {. +when not defined(zephyr): + proc inet_addr*(a1: cstring): InAddrT {.importc, header: "<arpa/inet.h>".} + proc inet_ntoa*(a1: InAddr): cstring {.importc, header: "<arpa/inet.h>".} + +proc inet_ntop*(a1: cint, a2: pointer | ptr InAddr | ptr In6Addr, a3: cstring, a4: int32): cstring {. importc:"(char *)$1", header: "<arpa/inet.h>".} -proc inet_pton*(a1: cint, a2: cstring, a3: pointer): cint {. +proc inet_pton*(a1: cint, a2: cstring, a3: pointer | ptr InAddr | ptr In6Addr): cint {. importc, header: "<arpa/inet.h>".} var @@ -166,29 +172,54 @@ proc IN6ADDR_LOOPBACK_INIT* (): In6Addr {.importc, header: "<netinet/in.h>".} # dirent.h proc closedir*(a1: ptr DIR): cint {.importc, header: "<dirent.h>".} -proc opendir*(a1: cstring): ptr DIR {.importc, header: "<dirent.h>".} -proc readdir*(a1: ptr DIR): ptr Dirent {.importc, header: "<dirent.h>".} +proc opendir*(a1: cstring): ptr DIR {.importc, header: "<dirent.h>", sideEffect.} +proc readdir*(a1: ptr DIR): ptr Dirent {.importc, header: "<dirent.h>", sideEffect.} proc readdir_r*(a1: ptr DIR, a2: ptr Dirent, a3: ptr ptr Dirent): cint {. - importc, header: "<dirent.h>".} + importc, header: "<dirent.h>", sideEffect.} proc rewinddir*(a1: ptr DIR) {.importc, header: "<dirent.h>".} proc seekdir*(a1: ptr DIR, a2: int) {.importc, header: "<dirent.h>".} proc telldir*(a1: ptr DIR): int {.importc, header: "<dirent.h>".} # dlfcn.h -proc dlclose*(a1: pointer): cint {.importc, header: "<dlfcn.h>".} -proc dlerror*(): cstring {.importc, header: "<dlfcn.h>".} -proc dlopen*(a1: cstring, a2: cint): pointer {.importc, header: "<dlfcn.h>".} -proc dlsym*(a1: pointer, a2: cstring): pointer {.importc, header: "<dlfcn.h>".} - -proc creat*(a1: cstring, a2: Mode): cint {.importc, header: "<fcntl.h>".} -proc fcntl*(a1: cint | SocketHandle, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".} -proc open*(a1: cstring, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".} +proc dlclose*(a1: pointer): cint {.importc, header: "<dlfcn.h>", sideEffect.} +proc dlerror*(): cstring {.importc, header: "<dlfcn.h>", sideEffect.} +proc dlopen*(a1: cstring, a2: cint): pointer {.importc, header: "<dlfcn.h>", sideEffect.} +proc dlsym*(a1: pointer, a2: cstring): pointer {.importc, header: "<dlfcn.h>", sideEffect.} + +proc creat*(a1: cstring, a2: Mode): cint {.importc, header: "<fcntl.h>", sideEffect.} +proc fcntl*(a1: cint | SocketHandle, a2: cint): cint {.varargs, importc, header: "<fcntl.h>", sideEffect.} +proc openImpl(a1: cstring, a2: cint): cint {.varargs, importc: "open", header: "<fcntl.h>", sideEffect.} +proc open*(a1: cstring, a2: cint, mode: Mode | cint = 0.Mode): cint {.inline.} = + # prevents bug #17888 + openImpl(a1, a2, mode) + proc posix_fadvise*(a1: cint, a2, a3: Off, a4: cint): cint {. importc, header: "<fcntl.h>".} -proc posix_fallocate*(a1: cint, a2, a3: Off): cint {. - importc, header: "<fcntl.h>".} -when not defined(haiku) and not defined(OpenBSD): +proc ftruncate*(a1: cint, a2: Off): cint {.importc, header: "<unistd.h>".} +when defined(osx): # 2001 POSIX evidently does not concern Apple + type FStore {.importc: "fstore_t", header: "<fcntl.h>", bycopy.} = object + fst_flags: uint32 ## IN: flags word + fst_posmode: cint ## IN: indicates offset field + fst_offset, ## IN: start of the region + fst_length, ## IN: size of the region + fst_bytesalloc: Off ## OUT: number of bytes allocated + var F_PEOFPOSMODE {.importc, header: "<fcntl.h>".}: cint + var F_ALLOCATEALL {.importc, header: "<fcntl.h>".}: uint32 + var F_PREALLOCATE {.importc, header: "<fcntl.h>".}: cint + proc posix_fallocate*(a1: cint, a2, a3: Off): cint = + var fst = FStore(fst_flags: F_ALLOCATEALL, fst_posmode: F_PEOFPOSMODE, + fst_offset: a2, fst_length: a3) + # Must also call ftruncate to match what POSIX does. Unlike posix_fallocate, + # this can shrink files. Could guard w/getFileSize, but caller likely knows + # present size & has no good reason to call this unless it is growing. + if fcntl(a1, F_PREALLOCATE, fst.addr) != cint(-1): ftruncate(a1, a2 + a3) + else: cint(-1) +else: + proc posix_fallocate*(a1: cint, a2, a3: Off): cint {. + importc, header: "<fcntl.h>".} + +when not defined(haiku) and not defined(openbsd): proc fmtmsg*(a1: int, a2: cstring, a3: cint, a4, a5, a6: cstring): cint {.importc, header: "<fmtmsg.h>".} @@ -205,7 +236,7 @@ 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>".} + a4: ptr Glob): cint {.importc, header: "<glob.h>", sideEffect.} ## Filename globbing. Use `os.walkPattern() <os.html#glob_1>`_ and similar. proc globfree*(a1: ptr Glob) {.importc, header: "<glob.h>".} @@ -234,31 +265,57 @@ proc dirname*(a1: cstring): cstring {.importc, header: "<libgen.h>".} proc localeconv*(): ptr Lconv {.importc, header: "<locale.h>".} proc setlocale*(a1: cint, a2: cstring): cstring {. - importc, header: "<locale.h>".} + importc, header: "<locale.h>", sideEffect.} proc strfmon*(a1: cstring, a2: int, a3: cstring): int {.varargs, importc, header: "<monetary.h>".} -when not defined(nintendoswitch): - proc mq_close*(a1: Mqd): cint {.importc, header: "<mqueue.h>".} - proc mq_getattr*(a1: Mqd, a2: ptr MqAttr): cint {. - importc, header: "<mqueue.h>".} - proc mq_notify*(a1: Mqd, a2: ptr SigEvent): cint {. +when not (defined(nintendoswitch) or defined(macos) or defined(macosx)): + proc mq_notify*(mqdes: Mqd, event: ptr SigEvent): cint {. importc, header: "<mqueue.h>".} - proc mq_open*(a1: cstring, a2: cint): Mqd {. + + proc mq_open*(name: cstring, flags: cint): Mqd {. varargs, importc, header: "<mqueue.h>".} - proc mq_receive*(a1: Mqd, a2: cstring, a3: int, a4: var int): int {. - importc, header: "<mqueue.h>".} - proc mq_send*(a1: Mqd, a2: cstring, a3: int, a4: int): cint {. + + proc mq_close*(mqdes: Mqd): cint {.importc, header: "<mqueue.h>".} + + proc mq_receive*( + mqdes: Mqd, + buffer: cstring, + length: csize_t, + priority: var cuint + ): int {.importc, header: "<mqueue.h>".} + + proc mq_timedreceive*( + mqdes: Mqd, + buffer: cstring, + length: csize_t, + priority: cuint, + timeout: ptr Timespec + ): int {.importc, header: "<mqueue.h>".} + + proc mq_send*( + mqdes: Mqd, + buffer: cstring, + length: csize_t, + priority: cuint + ): cint {.importc, header: "<mqueue.h>".} + + proc mq_timedsend*( + mqdes: Mqd, + buffer: cstring, + length: csize_t, + priority: cuint, + timeout: ptr Timespec + ): cint {.importc, header: "<mqueue.h>".} + + proc mq_getattr*(mqdes: Mqd, attribute: ptr MqAttr): cint {. importc, header: "<mqueue.h>".} - proc mq_setattr*(a1: Mqd, a2, a3: ptr MqAttr): cint {. + + proc mq_setattr*(mqdes: Mqd, newAttribute, oldAttribute: ptr MqAttr): cint {. importc, header: "<mqueue.h>".} - proc mq_timedreceive*(a1: Mqd, a2: cstring, a3: int, a4: int, - a5: ptr Timespec): int {.importc, header: "<mqueue.h>".} - proc mq_timedsend*(a1: Mqd, a2: cstring, a3: int, a4: int, - a5: ptr Timespec): cint {.importc, header: "<mqueue.h>".} - proc mq_unlink*(a1: cstring): cint {.importc, header: "<mqueue.h>".} + proc mq_unlink*(mqdes: cstring): cint {.importc, header: "<mqueue.h>".} proc getpwnam*(a1: cstring): ptr Passwd {.importc, header: "<pwd.h>".} @@ -446,7 +503,7 @@ proc pthread_spin_unlock*(a1: ptr Pthread_spinlock): cint {. proc pthread_testcancel*() {.importc, header: "<pthread.h>".} -proc exitnow*(code: int): void {.importc: "_exit", header: "<unistd.h>".} +proc exitnow*(code: int) {.importc: "_exit", header: "<unistd.h>".} proc access*(a1: cstring, a2: cint): cint {.importc, header: "<unistd.h>".} proc alarm*(a1: cint): cint {.importc, header: "<unistd.h>".} proc chdir*(a1: cstring): cint {.importc, header: "<unistd.h>".} @@ -459,54 +516,53 @@ proc dup*(a1: cint): cint {.importc, header: "<unistd.h>".} proc dup2*(a1, a2: cint): cint {.importc, header: "<unistd.h>".} proc encrypt*(a1: array[0..63, char], a2: cint) {.importc, header: "<unistd.h>".} -proc execl*(a1, a2: cstring): cint {.varargs, importc, header: "<unistd.h>".} -proc execle*(a1, a2: cstring): cint {.varargs, importc, header: "<unistd.h>".} -proc execlp*(a1, a2: cstring): cint {.varargs, importc, header: "<unistd.h>".} -proc execv*(a1: cstring, a2: cstringArray): cint {.importc, header: "<unistd.h>".} +proc execl*(a1, a2: cstring): cint {.varargs, importc, header: "<unistd.h>", sideEffect.} +proc execle*(a1, a2: cstring): cint {.varargs, importc, header: "<unistd.h>", sideEffect.} +proc execlp*(a1, a2: cstring): cint {.varargs, importc, header: "<unistd.h>", sideEffect.} +proc execv*(a1: cstring, a2: cstringArray): cint {.importc, header: "<unistd.h>", sideEffect.} proc execve*(a1: cstring, a2, a3: cstringArray): cint {. - importc, header: "<unistd.h>".} -proc execvp*(a1: cstring, a2: cstringArray): cint {.importc, header: "<unistd.h>".} -proc execvpe*(a1: cstring, a2: cstringArray, a3: cstringArray): cint {.importc, header: "<unistd.h>".} -proc fchown*(a1: cint, a2: Uid, a3: Gid): cint {.importc, header: "<unistd.h>".} -proc fchdir*(a1: cint): cint {.importc, header: "<unistd.h>".} + importc, header: "<unistd.h>", sideEffect.} +proc execvp*(a1: cstring, a2: cstringArray): cint {.importc, header: "<unistd.h>", sideEffect.} +proc execvpe*(a1: cstring, a2: cstringArray, a3: cstringArray): cint {.importc, header: "<unistd.h>", sideEffect.} +proc fchown*(a1: cint, a2: Uid, a3: Gid): cint {.importc, header: "<unistd.h>", sideEffect.} +proc fchdir*(a1: cint): cint {.importc, header: "<unistd.h>", sideEffect.} proc fdatasync*(a1: cint): cint {.importc, header: "<unistd.h>".} -proc fork*(): Pid {.importc, header: "<unistd.h>".} +proc fork*(): Pid {.importc, header: "<unistd.h>", sideEffect.} 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 getuid*(): Uid {.importc, header: "<unistd.h>".} +proc getcwd*(a1: cstring, a2: int): cstring {.importc, header: "<unistd.h>", sideEffect.} +proc getuid*(): Uid {.importc, header: "<unistd.h>", sideEffect.} ## returns the real user ID of the calling process -proc geteuid*(): Uid {.importc, header: "<unistd.h>".} +proc geteuid*(): Uid {.importc, header: "<unistd.h>", sideEffect.} ## returns the effective user ID of the calling process -proc getgid*(): Gid {.importc, header: "<unistd.h>".} +proc getgid*(): Gid {.importc, header: "<unistd.h>", sideEffect.} ## returns the real group ID of the calling process -proc getegid*(): Gid {.importc, header: "<unistd.h>".} +proc getegid*(): Gid {.importc, header: "<unistd.h>", sideEffect.} ## returns the effective group ID of the calling process proc getgroups*(a1: cint, a2: ptr array[0..255, Gid]): cint {. importc, header: "<unistd.h>".} -proc gethostid*(): int {.importc, header: "<unistd.h>".} -proc gethostname*(a1: cstring, a2: int): cint {.importc, header: "<unistd.h>".} -proc getlogin*(): cstring {.importc, header: "<unistd.h>".} -proc getlogin_r*(a1: cstring, a2: int): cint {.importc, header: "<unistd.h>".} +proc gethostid*(): int {.importc, header: "<unistd.h>", sideEffect.} +proc gethostname*(a1: cstring, a2: int): cint {.importc, header: "<unistd.h>", sideEffect.} +proc getlogin*(): cstring {.importc, header: "<unistd.h>", sideEffect.} +proc getlogin_r*(a1: cstring, a2: int): cint {.importc, header: "<unistd.h>", sideEffect.} proc getopt*(a1: cint, a2: cstringArray, a3: cstring): cint {. importc, header: "<unistd.h>".} proc getpgid*(a1: Pid): 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>", sideEffect.} ## returns the process ID (PID) of the calling process -proc getppid*(): Pid {.importc, header: "<unistd.h>".} +proc getppid*(): Pid {.importc, header: "<unistd.h>", sideEffect.} ## 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>", sideEffect.} ## returns the session ID of the calling process proc getwd*(a1: cstring): cstring {.importc, header: "<unistd.h>".} @@ -528,7 +584,8 @@ proc pread*(a1: cint, a2: pointer, a3: int, a4: Off): int {. proc pwrite*(a1: cint, a2: pointer, a3: int, a4: Off): int {. importc, header: "<unistd.h>".} proc read*(a1: cint, a2: pointer, a3: int): int {.importc, header: "<unistd.h>".} -proc readlink*(a1, a2: cstring, a3: int): int {.importc, header: "<unistd.h>".} +when not defined(nintendoswitch): + proc readlink*(a1, a2: cstring, a3: int): int {.importc, header: "<unistd.h>".} proc ioctl*(f: FileHandle, device: uint): int {.importc: "ioctl", header: "<sys/ioctl.h>", varargs, tags: [WriteIOEffect].} ## A system call for device-specific input/output operations and other @@ -547,7 +604,10 @@ proc setsid*(): Pid {.importc, header: "<unistd.h>".} proc setuid*(a1: Uid): cint {.importc, header: "<unistd.h>".} proc sleep*(a1: cint): cint {.importc, header: "<unistd.h>".} proc swab*(a1, a2: pointer, a3: int) {.importc, header: "<unistd.h>".} -proc symlink*(a1, a2: cstring): cint {.importc, header: "<unistd.h>".} +when not defined(nintendoswitch): + proc symlink*(a1, a2: cstring): cint {.importc, header: "<unistd.h>".} +else: + proc symlink*(a1, a2: cstring): cint = -1 proc sync*() {.importc, header: "<unistd.h>".} proc sysconf*(a1: cint): int {.importc, header: "<unistd.h>".} proc tcgetpgrp*(a1: cint): Pid {.importc, header: "<unistd.h>".} @@ -584,11 +644,13 @@ proc statvfs*(a1: cstring, a2: var Statvfs): cint {. proc fstatvfs*(a1: cint, a2: var Statvfs): cint {. importc, header: "<sys/statvfs.h>".} -proc chmod*(a1: cstring, a2: Mode): cint {.importc, header: "<sys/stat.h>".} -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>".} +proc chmod*(a1: cstring, a2: Mode): cint {.importc, header: "<sys/stat.h>", sideEffect.} +when defined(osx) or defined(freebsd): + proc lchmod*(a1: cstring, a2: Mode): cint {.importc, header: "<sys/stat.h>", sideEffect.} +proc fchmod*(a1: cint, a2: Mode): cint {.importc, header: "<sys/stat.h>", sideEffect.} +proc fstat*(a1: cint, a2: var Stat): cint {.importc, header: "<sys/stat.h>", sideEffect.} +proc lstat*(a1: cstring, a2: var Stat): cint {.importc, header: "<sys/stat.h>", sideEffect.} +proc mkdir*(a1: cstring, a2: Mode): cint {.importc, header: "<sys/stat.h>", sideEffect.} ## Use `os.createDir() <os.html#createDir,string>`_ and similar. proc mkfifo*(a1: cstring, a2: Mode): cint {.importc, header: "<sys/stat.h>".} @@ -637,7 +699,8 @@ proc posix_madvise*(a1: pointer, a2: int, a3: cint): cint {. importc, header: "<sys/mman.h>".} proc posix_mem_offset*(a1: pointer, a2: int, a3: var Off, a4: var int, a5: var cint): cint {.importc, header: "<sys/mman.h>".} -when not (defined(linux) and defined(amd64)) and not defined(nintendoswitch): +when not (defined(linux) and defined(amd64)) and not defined(nintendoswitch) and + not defined(haiku): proc posix_typed_mem_get_info*(a1: cint, a2: var Posix_typed_mem_info): cint {.importc, header: "<sys/mman.h>".} proc posix_typed_mem_open*(a1: cstring, a2, a3: cint): cint {. @@ -649,17 +712,17 @@ proc shm_unlink*(a1: cstring): cint {.importc, header: "<sys/mman.h>".} proc asctime*(a1: var Tm): cstring{.importc, header: "<time.h>".} proc asctime_r*(a1: var Tm, a2: cstring): cstring {.importc, header: "<time.h>".} -proc clock*(): Clock {.importc, header: "<time.h>".} +proc clock*(): Clock {.importc, header: "<time.h>", sideEffect.} proc clock_getcpuclockid*(a1: Pid, a2: var ClockId): cint {. - importc, header: "<time.h>".} + importc, header: "<time.h>", sideEffect.} proc clock_getres*(a1: ClockId, a2: var Timespec): cint {. - importc, header: "<time.h>".} + importc, header: "<time.h>", sideEffect.} proc clock_gettime*(a1: ClockId, a2: var Timespec): cint {. - importc, header: "<time.h>".} + importc, header: "<time.h>", sideEffect.} proc clock_nanosleep*(a1: ClockId, a2: cint, a3: var Timespec, - a4: var Timespec): cint {.importc, header: "<time.h>".} + a4: var Timespec): cint {.importc, header: "<time.h>", sideEffect.} proc clock_settime*(a1: ClockId, a2: var Timespec): cint {. - importc, header: "<time.h>".} + importc, header: "<time.h>", sideEffect.} proc `==`*(a, b: Time): bool {.borrow.} proc `-`*(a, b: Time): Time {.borrow.} @@ -673,11 +736,11 @@ proc localtime*(a1: var Time): ptr Tm {.importc, header: "<time.h>".} proc localtime_r*(a1: var Time, a2: var Tm): ptr Tm {.importc, header: "<time.h>".} proc mktime*(a1: var Tm): Time {.importc, header: "<time.h>".} proc timegm*(a1: var Tm): Time {.importc, header: "<time.h>".} -proc nanosleep*(a1, a2: var Timespec): cint {.importc, header: "<time.h>".} +proc nanosleep*(a1, a2: var Timespec): cint {.importc, header: "<time.h>", sideEffect.} proc strftime*(a1: cstring, a2: int, a3: cstring, a4: var Tm): int {.importc, header: "<time.h>".} proc strptime*(a1, a2: cstring, a3: var Tm): cstring {.importc, header: "<time.h>".} -proc time*(a1: var Time): Time {.importc, header: "<time.h>".} +proc time*(a1: var Time): Time {.importc, header: "<time.h>", sideEffect.} proc timer_create*(a1: ClockId, a2: var SigEvent, a3: var Timer): cint {.importc, header: "<time.h>".} proc timer_delete*(a1: Timer): cint {.importc, header: "<time.h>".} @@ -689,11 +752,11 @@ proc timer_settime*(a1: Timer, a2: cint, a3: var Itimerspec, proc tzset*() {.importc, header: "<time.h>".} -proc wait*(a1: ptr cint): Pid {.importc, discardable, header: "<sys/wait.h>".} +proc wait*(a1: ptr cint): Pid {.importc, discardable, header: "<sys/wait.h>", sideEffect.} proc waitid*(a1: cint, a2: Id, a3: var SigInfo, a4: cint): cint {. - importc, header: "<sys/wait.h>".} + importc, header: "<sys/wait.h>", sideEffect.} proc waitpid*(a1: Pid, a2: var cint, a3: cint): Pid {. - importc, header: "<sys/wait.h>".} + importc, header: "<sys/wait.h>", sideEffect.} type Rusage* {.importc: "struct rusage", header: "<sys/resource.h>", bycopy.} = object @@ -704,7 +767,7 @@ type Rusage* {.importc: "struct rusage", header: "<sys/resource.h>", ru_nsignals*, ru_nvcsw*, ru_nivcsw*: clong # switching activity proc wait4*(pid: Pid, status: ptr cint, options: cint, rusage: ptr Rusage): Pid - {.importc, header: "<sys/wait.h>".} + {.importc, header: "<sys/wait.h>", sideEffect.} const RUSAGE_SELF* = cint(0) @@ -717,8 +780,8 @@ proc getrusage*(who: cint, rusage: ptr Rusage): cint proc bsd_signal*(a1: cint, a2: proc (x: pointer) {.noconv.}) {. importc, header: "<signal.h>".} -proc kill*(a1: Pid, a2: cint): cint {.importc, header: "<signal.h>".} -proc killpg*(a1: Pid, a2: cint): cint {.importc, header: "<signal.h>".} +proc kill*(a1: Pid, a2: cint): cint {.importc, header: "<signal.h>", sideEffect.} +proc killpg*(a1: Pid, a2: cint): cint {.importc, header: "<signal.h>", sideEffect.} proc pthread_kill*(a1: Pthread, a2: cint): cint {.importc, header: "<signal.h>".} proc pthread_sigmask*(a1: cint, a2, a3: var Sigset): cint {. importc, header: "<signal.h>".} @@ -762,6 +825,13 @@ else: proc sigtimedwait*(a1: var Sigset, a2: var SigInfo, a3: var Timespec): cint {.importc, header: "<signal.h>".} +when defined(sunos) or defined(solaris): + # The following compile time flag is needed on Illumos/Solaris to use the POSIX + # `sigwait` implementation. See the documentation here: + # https://docs.oracle.com/cd/E19455-01/806-5257/6je9h033k/index.html + # https://www.illumos.org/man/2/sigwait + {.passc: "-D_POSIX_PTHREAD_SEMANTICS".} + proc sigwait*(a1: var Sigset, a2: var cint): cint {. importc, header: "<signal.h>".} proc sigwaitinfo*(a1: var Sigset, a2: var SigInfo): cint {. @@ -874,15 +944,9 @@ proc CMSG_NXTHDR*(mhdr: ptr Tmsghdr, cmsg: ptr Tcmsghdr): ptr Tcmsghdr {. proc CMSG_FIRSTHDR*(mhdr: ptr Tmsghdr): ptr Tcmsghdr {. importc, header: "<sys/socket.h>".} -proc CMSG_SPACE*(len: csize): csize {. - importc, header: "<sys/socket.h>", deprecated: "argument `len` should be of type `csize_t`".} - proc CMSG_SPACE*(len: csize_t): csize_t {. importc, header: "<sys/socket.h>".} -proc CMSG_LEN*(len: csize): csize {. - importc, header: "<sys/socket.h>", deprecated: "argument `len` should be of type `csize_t`".} - proc CMSG_LEN*(len: csize_t): csize_t {. importc, header: "<sys/socket.h>".} @@ -892,11 +956,15 @@ const proc `==`*(x, y: SocketHandle): bool {.borrow.} proc accept*(a1: SocketHandle, a2: ptr SockAddr, a3: ptr SockLen): SocketHandle {. - importc, header: "<sys/socket.h>".} + importc, header: "<sys/socket.h>", sideEffect.} + +when defined(linux) or defined(bsd) or defined(nuttx): + proc accept4*(a1: SocketHandle, a2: ptr SockAddr, a3: ptr SockLen, + flags: cint): SocketHandle {.importc, header: "<sys/socket.h>".} proc bindSocket*(a1: SocketHandle, a2: ptr SockAddr, a3: SockLen): cint {. importc: "bind", header: "<sys/socket.h>".} - ## is Posix's ``bind``, because ``bind`` is a reserved word + ## is Posix's `bind`, because `bind` is a reserved word proc connect*(a1: SocketHandle, a2: ptr SockAddr, a3: SockLen): cint {. importc, header: "<sys/socket.h>".} @@ -909,21 +977,21 @@ proc getsockopt*(a1: SocketHandle, a2, a3: cint, a4: pointer, a5: ptr SockLen): importc, header: "<sys/socket.h>".} proc listen*(a1: SocketHandle, a2: cint): cint {. - importc, header: "<sys/socket.h>".} + importc, header: "<sys/socket.h>", sideEffect.} proc recv*(a1: SocketHandle, a2: pointer, a3: int, a4: cint): int {. - importc, header: "<sys/socket.h>".} + importc, header: "<sys/socket.h>", sideEffect.} proc recvfrom*(a1: SocketHandle, a2: pointer, a3: int, a4: cint, a5: ptr SockAddr, a6: ptr SockLen): int {. - importc, header: "<sys/socket.h>".} + importc, header: "<sys/socket.h>", sideEffect.} proc recvmsg*(a1: SocketHandle, a2: ptr Tmsghdr, a3: cint): int {. - importc, header: "<sys/socket.h>".} + importc, header: "<sys/socket.h>", sideEffect.} proc send*(a1: SocketHandle, a2: pointer, a3: int, a4: cint): int {. - importc, header: "<sys/socket.h>".} + importc, header: "<sys/socket.h>", sideEffect.} proc sendmsg*(a1: SocketHandle, a2: ptr Tmsghdr, a3: cint): int {. - importc, header: "<sys/socket.h>".} + importc, header: "<sys/socket.h>", sideEffect.} proc sendto*(a1: SocketHandle, a2: pointer, a3: int, a4: cint, a5: ptr SockAddr, a6: SockLen): int {. - importc, header: "<sys/socket.h>".} + importc, header: "<sys/socket.h>", sideEffect.} proc setsockopt*(a1: SocketHandle, a2, a3: cint, a4: pointer, a5: SockLen): cint {. importc, header: "<sys/socket.h>".} proc shutdown*(a1: SocketHandle, a2: cint): cint {. @@ -956,9 +1024,15 @@ proc IN6_IS_ADDR_LINKLOCAL* (a1: ptr In6Addr): cint {. proc IN6_IS_ADDR_SITELOCAL* (a1: ptr In6Addr): cint {. importc, header: "<netinet/in.h>".} ## Unicast site-local address. -proc IN6_IS_ADDR_V4MAPPED* (a1: ptr In6Addr): cint {. - importc, header: "<netinet/in.h>".} - ## IPv4 mapped address. +when defined(lwip): + proc IN6_IS_ADDR_V4MAPPED*(ipv6_address: ptr In6Addr): cint = + var bits32: ptr array[4, uint32] = cast[ptr array[4, uint32]](ipv6_address) + return (bits32[1] == 0'u32 and bits32[2] == htonl(0x0000FFFF)).cint +else: + proc IN6_IS_ADDR_V4MAPPED* (a1: ptr In6Addr): cint {. + importc, header: "<netinet/in.h>".} + ## IPv4 mapped address. + proc IN6_IS_ADDR_V4COMPAT* (a1: ptr In6Addr): cint {. importc, header: "<netinet/in.h>".} ## IPv4-compatible address. @@ -982,7 +1056,7 @@ proc endhostent*() {.importc, header: "<netdb.h>".} proc endnetent*() {.importc, header: "<netdb.h>".} proc endprotoent*() {.importc, header: "<netdb.h>".} proc endservent*() {.importc, header: "<netdb.h>".} -proc freeaddrinfo*(a1: ptr AddrInfo) {.importc, header: "<netdb.h>".} +proc freeAddrInfo*(a1: ptr AddrInfo) {.importc: "freeaddrinfo", header: "<netdb.h>".} proc gai_strerror*(a1: cint): cstring {.importc:"(char *)$1", header: "<netdb.h>".} @@ -1020,22 +1094,37 @@ proc setnetent*(a1: cint) {.importc, header: "<netdb.h>".} proc setprotoent*(a1: cint) {.importc, header: "<netdb.h>".} proc setservent*(a1: cint) {.importc, header: "<netdb.h>".} -proc poll*(a1: ptr TPollfd, a2: Tnfds, a3: int): cint {. - importc, header: "<poll.h>".} +when not defined(lwip): + proc poll*(a1: ptr TPollfd, a2: Tnfds, a3: int): cint {. + importc, header: "<poll.h>", sideEffect.} proc realpath*(name, resolved: cstring): cstring {. importc: "realpath", header: "<stdlib.h>".} -proc mkstemp*(tmpl: cstring): cint {.importc, header: "<stdlib.h>".} +proc mkstemp*(tmpl: cstring): cint {.importc, header: "<stdlib.h>", sideEffect.} ## 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. + ## .. warning:: The `tmpl` argument is written to by `mkstemp` and thus + ## can't be a string literal. If in doubt make a copy of the cstring before + ## passing it in. -proc mkdtemp*(tmpl: cstring): pointer {.importc, header: "<stdlib.h>".} +proc mkstemps*(tmpl: cstring, suffixlen: int): cint {.importc, header: "<stdlib.h>", sideEffect.} + ## Creates a unique temporary file. + ## + ## .. warning:: The `tmpl` argument is written to by `mkstemps` and thus + ## can't be a string literal. If in doubt make a copy of the cstring before + ## passing it in. + +proc mkdtemp*(tmpl: cstring): pointer {.importc, header: "<stdlib.h>", sideEffect.} + +when defined(linux) or defined(bsd) or defined(osx): + proc mkostemp*(tmpl: cstring, oflags: cint): cint {.importc, header: "<stdlib.h>", sideEffect.} + proc mkostemps*(tmpl: cstring, suffixlen: cint, oflags: cint): cint {.importc, header: "<stdlib.h>", sideEffect.} + + proc posix_memalign*(memptr: pointer, alignment: csize_t, size: csize_t): cint {.importc, header: "<stdlib.h>".} proc utimes*(path: cstring, times: ptr array[2, Timeval]): int {. - importc: "utimes", header: "<sys/time.h>".} + importc: "utimes", header: "<sys/time.h>", sideEffect.} ## Sets file access and modification times. ## ## Pass the filename and an array of times to set the access and modification @@ -1050,15 +1139,15 @@ proc handle_signal(sig: cint, handler: proc (a: cint) {.noconv.}) {.importc: "si template onSignal*(signals: varargs[cint], body: untyped) = ## Setup code to be executed when Unix signals are received. The - ## currently handled signal is injected as ``sig`` into the calling + ## currently handled signal is injected as `sig` into the calling ## scope. ## ## Example: - ## - ## .. code-block:: - ## from posix import SIGINT, SIGTERM, onSignal + ## ```Nim + ## from std/posix import SIGINT, SIGTERM, onSignal ## onSignal(SIGINT, SIGTERM): ## echo "bye from signal ", sig + ## ``` for s in signals: handle_signal(s, @@ -1075,12 +1164,12 @@ type ## The getrlimit() and setrlimit() system calls get and set resource limits respectively. ## Each resource has an associated soft and hard limit, as defined by the RLimit structure -proc setrlimit*(resource: cint, rlp: var RLimit): cint - {.importc: "setrlimit",header: "<sys/resource.h>".} +proc setrlimit*(resource: cint, rlp: var RLimit): cint {. + importc: "setrlimit", header: "<sys/resource.h>".} ## The setrlimit() system calls sets resource limits. -proc getrlimit*(resource: cint, rlp: var RLimit): cint - {.importc: "getrlimit",header: "<sys/resource.h>".} +proc getrlimit*(resource: cint, rlp: var RLimit): cint {. + importc: "getrlimit", header: "<sys/resource.h>".} ## The getrlimit() system call gets resource limits. when defined(nimHasStyleChecks): |