diff options
Diffstat (limited to 'lib/posix/posix_other.nim')
-rw-r--r-- | lib/posix/posix_other.nim | 235 |
1 files changed, 156 insertions, 79 deletions
diff --git a/lib/posix/posix_other.nim b/lib/posix/posix_other.nim index b7570bd15..ea8731405 100644 --- a/lib/posix/posix_other.nim +++ b/lib/posix/posix_other.nim @@ -7,34 +7,42 @@ # distribution, for details about the copyright. # -{.deadCodeElim: on.} # dce option deprecated +when defined(nimHasStyleChecks): + {.push styleChecks: off.} -const - hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays - hasAioH = defined(linux) +when defined(freertos) or defined(zephyr): + const + hasSpawnH = false # should exist for every Posix system nowadays + hasAioH = false +else: + const + hasSpawnH = true # should exist for every Posix system nowadays + hasAioH = defined(linux) when defined(linux) and not defined(android): # On Linux: # timer_{create,delete,settime,gettime}, # clock_{getcpuclockid, getres, gettime, nanosleep, settime} lives in librt - {.passL: "-lrt".} + {.passl: "-lrt".} when defined(solaris): # On Solaris hstrerror lives in libresolv - {.passL: "-lresolv".} + {.passl: "-lresolv".} type DIR* {.importc: "DIR", header: "<dirent.h>", incompleteStruct.} = object ## A type representing a directory stream. -{.deprecated: [TDIR: DIR].} type SocketHandle* = distinct cint # The type used to represent socket descriptors -{.deprecated: [TSocketHandle: SocketHandle].} - type - Time* {.importc: "time_t", header: "<time.h>".} = distinct clong + Time* {.importc: "time_t", header: "<time.h>".} = distinct ( + when defined(nimUse64BitCTime): + int64 + else: + clong + ) Timespec* {.importc: "struct timespec", header: "<time.h>", final, pure.} = object ## struct timespec @@ -43,6 +51,9 @@ type Dirent* {.importc: "struct dirent", header: "<dirent.h>", final, pure.} = object ## dirent_t struct + when defined(haiku): + d_dev*: Dev ## Device (not POSIX) + d_pdev*: Dev ## Parent device (only for queries) (not POSIX) d_ino*: Ino ## File serial number. when defined(dragonfly): # DragonflyBSD doesn't have `d_reclen` field. @@ -53,7 +64,10 @@ type d_type*: int8 ## Type of file; not supported by all filesystem types. ## (not POSIX) when defined(linux) or defined(openbsd): - d_off*: Off ## Not an offset. Value that ``telldir()`` would return. + d_off*: Off ## Not an offset. Value that `telldir()` would return. + elif defined(haiku): + d_pino*: Ino ## Parent inode (only for queries) (not POSIX) + d_reclen*: cushort ## Length of this record. (not POSIX) d_name*: array[0..255, char] ## Name of entry. @@ -143,7 +157,13 @@ type Id* {.importc: "id_t", header: "<sys/types.h>".} = int Ino* {.importc: "ino_t", header: "<sys/types.h>".} = int Key* {.importc: "key_t", header: "<sys/types.h>".} = int - Mode* {.importc: "mode_t", header: "<sys/types.h>".} = cint + Mode* {.importc: "mode_t", header: "<sys/types.h>".} = ( + when defined(android) or defined(macos) or defined(macosx) or + (defined(bsd) and not defined(openbsd) and not defined(netbsd)): + uint16 + else: + uint32 + ) Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = int Off* {.importc: "off_t", header: "<sys/types.h>".} = int64 Pid* {.importc: "pid_t", header: "<sys/types.h>".} = int32 @@ -278,7 +298,7 @@ type sigev_signo*: cint ## Signal number. sigev_value*: SigVal ## Signal value. sigev_notify_function*: proc (x: SigVal) {.noconv.} ## Notification func. - sigev_notify_attributes*: ptr PthreadAttr ## Notification attributes. + sigev_notify_attributes*: ptr Pthread_attr ## Notification attributes. SigVal* {.importc: "union sigval", header: "<signal.h>", final, pure.} = object ## struct sigval @@ -350,31 +370,7 @@ type uc_stack*: Stack ## The stack used by this context. uc_mcontext*: Mcontext ## A machine-specific representation of the saved ## context. -{.deprecated: [TOff: Off, TPid: Pid, TGid: Gid, TMode: Mode, TDev: Dev, - TNlink: Nlink, TStack: Stack, TGroup: Group, TMqd: Mqd, - TPasswd: Passwd, TClock: Clock, TClockId: ClockId, TKey: Key, - TSem: Sem, Tpthread_attr: PthreadAttr, Ttimespec: Timespec, - Tdirent: Dirent, TFTW: FTW, TGlob: Glob, - # Tflock: Flock, # Naming conflict if we drop the `T` - Ticonv: Iconv, Tlconv: Lconv, TMqAttr: MqAttr, Tblkcnt: Blkcnt, - Tblksize: Blksize, Tfsblkcnt: Fsblkcnt, Tfsfilcnt: Fsfilcnt, - Tid: Id, Tino: Ino, Tpthread_barrier: Pthread_barrier, - Tpthread_barrierattr: Pthread_barrierattr, Tpthread_cond: Pthread_cond, - TPthread_condattr: Pthread_condattr, Tpthread_key: Pthread_key, - Tpthread_mutex: Pthread_mutex, Tpthread_mutexattr: Pthread_mutexattr, - Tpthread_once: Pthread_once, Tpthread_rwlock: Pthread_rwlock, - Tpthread_rwlockattr: Pthread_rwlockattr, Tpthread_spinlock: Pthread_spinlock, - Tpthread: Pthread, Tsuseconds: Suseconds, Ttimer: Timer, - Ttrace_attr: Trace_attr, Ttrace_event_id: Trace_event_id, - Ttrace_event_set: Trace_event_set, Ttrace_id: Trace_id, - Tuid: Uid, Tuseconds: Useconds, Tutsname: Utsname, Tipc_perm: Ipc_perm, - TStat: Stat, TStatvfs: Statvfs, Tposix_typed_mem_info: Posix_typed_mem_info, - Ttm: Tm, titimerspec: Itimerspec, Tsig_atomic: Sig_atomic, Tsigset: Sigset, - TsigEvent: SigEvent, TsigVal: SigVal, TSigaction: Sigaction, - TSigStack: SigStack, TsigInfo: SigInfo, Tnl_item: Nl_item, - Tnl_catd: Nl_catd, Tsched_param: Sched_param, - # TFdSet: FdSet, # Naming conflict if we drop the `T` - Tmcontext: Mcontext, Tucontext: Ucontext].} + when hasAioH: type Taiocb* {.importc: "struct aiocb", header: "<aio.h>", @@ -395,32 +391,92 @@ when hasSpawnH: header: "<spawn.h>", final, pure.} = object when defined(linux): + const Sockaddr_max_length* = 255 # from sys/un.h const Sockaddr_un_path_length* = 108 +elif defined(zephyr): + when defined(net_ipv6): + const Sockaddr_max_length* = 24 + elif defined(net_raw): + const Sockaddr_max_length* = 20 + elif defined(net_ipv4): + const Sockaddr_max_length* = 8 + else: + const Sockaddr_max_length* = 255 # just for compilation purposes + + const Sockaddr_un_path_length* = Sockaddr_max_length + # Zephyr is heavily customizable so it's easy to get to a state + # where Nim & Zephyr IPv6 settings are out of sync, causing painful runtime failures. + when defined(net_ipv4) or defined(net_ipv6) or defined(net_raw): + {.emit: ["NIM_STATIC_ASSERT(NET_SOCKADDR_MAX_SIZE == ", + Sockaddr_max_length, + ",\"NET_SOCKADDR_MAX_SIZE and Sockaddr_max_length size mismatch!", + " Check that Nim and Zephyr IPv4/IPv6 settings match.", + " Try adding -d:net_ipv6 to enable IPv6 for Nim on Zephyr.\" );"].} +elif defined(freertos) or defined(lwip): + const Sockaddr_max_length* = 14 + const Sockaddr_un_path_length* = 108 else: + const Sockaddr_max_length* = 255 # according to http://pubs.opengroup.org/onlinepubs/009604499/basedefs/sys/un.h.html # this is >=92 const Sockaddr_un_path_length* = 92 type - Socklen* {.importc: "socklen_t", header: "<sys/socket.h>".} = cuint - TSa_Family* {.importc: "sa_family_t", header: "<sys/socket.h>".} = cint + SockLen* {.importc: "socklen_t", header: "<sys/socket.h>".} = cuint + TSa_Family* {.importc: "sa_family_t", header: "<sys/socket.h>".} = cushort + +when defined(lwip): + type + SockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>", + pure, final.} = object ## struct sockaddr + sa_len*: uint8 ## Address family. + sa_family*: TSa_Family ## Address family. + sa_data*: array[0..Sockaddr_max_length-sizeof(uint8)-sizeof(TSa_Family), char] ## Socket address (variable-length data). + + Sockaddr_storage* {.importc: "struct sockaddr_storage", + header: "<sys/socket.h>", + pure, final.} = object ## struct sockaddr_storage + s2_len*: uint8 ## Address family. + ss_family*: TSa_Family ## Address family. + s2_data1*: array[2, char] ## Address family. + s2_data2*: array[3, uint32] ## Address family. + when defined(lwip6) or defined(net_ipv6): + s2_data3*: array[3, uint32] ## Address family. +elif defined(zephyr): + type + SockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>", + pure, final.} = object ## struct sockaddr + sa_family*: TSa_Family ## Address family. + data*: array[0..Sockaddr_max_length-sizeof(TSa_Family), char] ## Socket address (variable-length data). + + Sockaddr_storage* {.importc: "struct sockaddr_storage", + header: "<sys/socket.h>", + pure, final.} = object ## struct sockaddr_storage + ss_family*: TSa_Family ## Address family. + data*: array[0..Sockaddr_max_length-sizeof(TSa_Family), char] ## Socket address (variable-length data). + {.emit: ["NIM_STATIC_ASSERT(sizeof(struct sockaddr) == ", sizeof(Sockaddr), ",\"struct size mismatch\" );"].} + {.emit: ["NIM_STATIC_ASSERT(sizeof(struct sockaddr_storage) == ", sizeof(Sockaddr_storage), ",\"struct size mismatch\" );"].} +else: + type + SockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>", + pure, final.} = object ## struct sockaddr + sa_family*: TSa_Family ## Address family. + sa_data*: array[0..Sockaddr_max_length-sizeof(TSa_Family), char] ## Socket address (variable-length data). - SockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>", - pure, final.} = object ## struct sockaddr - sa_family*: TSa_Family ## Address family. - sa_data*: array[0..255, char] ## Socket address (variable-length data). + Sockaddr_storage* {.importc: "struct sockaddr_storage", + header: "<sys/socket.h>", + pure, final.} = object ## struct sockaddr_storage + ss_family*: TSa_Family ## Address family. +type Sockaddr_un* {.importc: "struct sockaddr_un", header: "<sys/un.h>", pure, final.} = object ## struct sockaddr_un sun_family*: TSa_Family ## Address family. - sun_path*: array[0..Sockaddr_un_path_length-1, char] ## Socket path + sun_path*: array[0..Sockaddr_un_path_length-sizeof(TSa_Family), char] ## Socket path - Sockaddr_storage* {.importc: "struct sockaddr_storage", - header: "<sys/socket.h>", - pure, final.} = object ## struct sockaddr_storage - ss_family*: TSa_Family ## Address family. +type Tif_nameindex* {.importc: "struct if_nameindex", final, pure, header: "<net/if.h>".} = object ## struct if_nameindex if_index*: cint ## Numeric index of the interface. @@ -430,22 +486,22 @@ type IOVec* {.importc: "struct iovec", pure, final, header: "<sys/uio.h>".} = object ## struct iovec iov_base*: pointer ## Base address of a memory region for input or output. - iov_len*: int ## The size of the memory pointed to by iov_base. + iov_len*: csize_t ## The size of the memory pointed to by iov_base. Tmsghdr* {.importc: "struct msghdr", pure, final, header: "<sys/socket.h>".} = object ## struct msghdr msg_name*: pointer ## Optional address. - msg_namelen*: Socklen ## Size of address. + msg_namelen*: SockLen ## Size of address. msg_iov*: ptr IOVec ## Scatter/gather array. msg_iovlen*: cint ## Members in msg_iov. msg_control*: pointer ## Ancillary data; see below. - msg_controllen*: Socklen ## Ancillary data buffer len. + msg_controllen*: SockLen ## Ancillary data buffer len. msg_flags*: cint ## Flags on received message. Tcmsghdr* {.importc: "struct cmsghdr", pure, final, header: "<sys/socket.h>".} = object ## struct cmsghdr - cmsg_len*: Socklen ## Data byte count, including the cmsghdr. + cmsg_len*: SockLen ## Data byte count, including the cmsghdr. cmsg_level*: cint ## Originating protocol. cmsg_type*: cint ## Protocol-specific type. @@ -464,6 +520,7 @@ type header: "<netinet/in.h>".} = object ## struct in_addr s_addr*: InAddrScalar + # TODO: Fixme for FreeRTOS/LwIP, these are incorrect Sockaddr_in* {.importc: "struct sockaddr_in", pure, final, header: "<netinet/in.h>".} = object ## struct sockaddr_in sin_family*: TSa_Family ## AF_INET. @@ -534,25 +591,25 @@ type ai_family*: cint ## Address family of socket. ai_socktype*: cint ## Socket type. ai_protocol*: cint ## Protocol of socket. - ai_addrlen*: Socklen ## Length of socket address. + ai_addrlen*: SockLen ## Length of socket address. ai_addr*: ptr SockAddr ## Socket address of socket. ai_canonname*: cstring ## Canonical name of service location. ai_next*: ptr AddrInfo ## Pointer to next in list. - TPollfd* {.importc: "struct pollfd", pure, final, - header: "<poll.h>".} = object ## struct pollfd - fd*: cint ## The following descriptor being polled. - events*: cshort ## The input event flags (see below). - revents*: cshort ## The output event flags (see below). - - Tnfds* {.importc: "nfds_t", header: "<poll.h>".} = cint - -{.deprecated: [TSockaddr_in: Sockaddr_in, TAddrinfo: AddrInfo, - TSockAddr: SockAddr, TSockLen: SockLen, TTimeval: Timeval, - Tsockaddr_storage: Sockaddr_storage, Tsockaddr_in6: Sockaddr_in6, - Thostent: Hostent, TServent: Servent, - TInAddr: InAddr, TIOVec: IOVec, TInPort: InPort, TInAddrT: InAddrT, - TIn6Addr: In6Addr, TInAddrScalar: InAddrScalar, TProtoent: Protoent].} +when not defined(lwip): + type + TPollfd* {.importc: "struct pollfd", pure, final, + header: "<poll.h>".} = object ## struct pollfd + fd*: cint ## The following descriptor being polled. + events*: cshort ## The input event flags (see below). + revents*: cshort ## The output event flags (see below). + + when defined(zephyr): + type + Tnfds* = distinct cint + else: + type + Tnfds* {.importc: "nfds_t", header: "<poll.h>".} = cint var errno* {.importc, header: "<errno.h>".}: cint ## error variable @@ -561,7 +618,10 @@ var timezone* {.importc, header: "<time.h>".}: int # Regenerate using detect.nim! -include posix_other_consts +when defined(lwip): + include posix_freertos_consts +else: + include posix_other_consts when defined(linux): var @@ -574,51 +634,65 @@ else: when defined(linux) or defined(nimdoc): when defined(alpha) or defined(mips) or defined(mipsel) or defined(mips64) or defined(mips64el) or defined(parisc) or - defined(sparc) or defined(nimdoc): + defined(sparc) or defined(sparc64) or defined(nimdoc): const SO_REUSEPORT* = cint(0x0200) ## Multiple binding: load balancing on incoming TCP connections ## or UDP packets. (Requires Linux kernel > 3.9) else: const SO_REUSEPORT* = cint(15) +elif defined(nuttx): + # Not supported, use SO_REUSEADDR to avoid compilation errors. + var SO_REUSEPORT* {.importc: "SO_REUSEADDR", header: "<sys/socket.h>".}: cint else: var SO_REUSEPORT* {.importc, header: "<sys/socket.h>".}: cint +when defined(linux) or defined(bsd) or defined(nuttx): + var SOCK_CLOEXEC* {.importc, header: "<sys/socket.h>".}: cint + when defined(macosx): - # We can't use the NOSIGNAL flag in the ``send`` function, it has no effect + # We can't use the NOSIGNAL flag in the `send` function, it has no effect # Instead we should use SO_NOSIGPIPE in setsockopt const MSG_NOSIGNAL* = 0'i32 var SO_NOSIGPIPE* {.importc, header: "<sys/socket.h>".}: cint elif defined(solaris): - # Solaris dont have MSG_NOSIGNAL + # Solaris doesn't have MSG_NOSIGNAL const MSG_NOSIGNAL* = 0'i32 +elif defined(zephyr) or defined(freertos) or defined(lwip): + # LwIP/FreeRTOS doesn't have MSG_NOSIGNAL + const + MSG_NOSIGNAL* = 0x20'i32 else: var MSG_NOSIGNAL* {.importc, header: "<sys/socket.h>".}: cint ## No SIGPIPE generated when an attempt to send is made on a stream-oriented socket that is no longer connected. +when defined(haiku): + const + SIGKILLTHR* = 21 ## BeOS specific: Kill just the thread, not team + when hasSpawnH: when defined(linux): - # better be safe than sorry; Linux has this flag, macosx doesn't, don't - # know about the other OSes + # better be safe than sorry; Linux has this flag, macosx and NuttX don't, + # don't know about the other OSes - # Non-GNU systems like TCC and musl-libc don't define __USE_GNU, so we + # Non-GNU systems like TCC and musl-libc don't define __USE_GNU, so we # can't get the magic number from spawn.h const POSIX_SPAWN_USEVFORK* = cint(0x40) else: - # macosx lacks this, so we define the constant to be 0 to not affect + # macosx and NuttX lack this, so we define the constant to be 0 to not affect # OR'ing of flags: const POSIX_SPAWN_USEVFORK* = cint(0) # <sys/wait.h> proc WEXITSTATUS*(s: cint): cint {.importc, header: "<sys/wait.h>".} - ## Exit code, iff WIFEXITED(s) + ## Exit code, if WIFEXITED(s) proc WTERMSIG*(s: cint): cint {.importc, header: "<sys/wait.h>".} - ## Termination signal, iff WIFSIGNALED(s) + ## Termination signal, if WIFSIGNALED(s) proc WSTOPSIG*(s: cint): cint {.importc, header: "<sys/wait.h>".} - ## Stop signal, iff WIFSTOPPED(s) + ## Stop signal, if WIFSTOPPED(s) proc WIFEXITED*(s: cint): bool {.importc, header: "<sys/wait.h>".} ## True if child exited normally. proc WIFSIGNALED*(s: cint): bool {.importc, header: "<sys/wait.h>".} @@ -627,3 +701,6 @@ proc WIFSTOPPED*(s: cint): bool {.importc, header: "<sys/wait.h>".} ## True if child is currently stopped. proc WIFCONTINUED*(s: cint): bool {.importc, header: "<sys/wait.h>".} ## True if child has been continued. + +when defined(nimHasStyleChecks): + {.pop.} |