diff options
Diffstat (limited to 'lib')
37 files changed, 4189 insertions, 2432 deletions
diff --git a/lib/deprecated/pure/sockets.nim b/lib/deprecated/pure/sockets.nim index 34c2e7a7d..415078126 100644 --- a/lib/deprecated/pure/sockets.nim +++ b/lib/deprecated/pure/sockets.nim @@ -219,7 +219,7 @@ template htons(x: uint16): expr = sockets.ntohs(x) when defined(Posix): - proc toInt(domain: Domain): cint = + proc toInt(domain: Domain): TSa_Family = case domain of AF_UNIX: result = posix.AF_UNIX of AF_INET: result = posix.AF_INET diff --git a/lib/nimbase.h b/lib/nimbase.h index 714623d4e..70391024f 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -26,14 +26,14 @@ __clang__ /*------------ declaring a custom attribute to support using LLVM's Address Sanitizer ------------ */ /* - This definition exists to provide support for using the LLVM ASAN (Address SANitizer) tooling with Nim. This + This definition exists to provide support for using the LLVM ASAN (Address SANitizer) tooling with Nim. This should only be used to mark implementations of the GC system that raise false flags with the ASAN tooling, or - for functions that are hot and need to be disabled for performance reasons. Based on the official ASAN - documentation, both the clang and gcc compilers are supported. In addition to that, a check is performed to + for functions that are hot and need to be disabled for performance reasons. Based on the official ASAN + documentation, both the clang and gcc compilers are supported. In addition to that, a check is performed to verify that the necessary attribute is supported by the compiler. To flag a proc as ignored, append the following code pragma to the proc declaration: - {.codegenDecl: "CLANG_NO_SANITIZE_ADDRESS $# $#$#".} + {.codegenDecl: "CLANG_NO_SANITIZE_ADDRESS $# $#$#".} For further information, please refer to the official documentation: https://github.com/google/sanitizers/wiki/AddressSanitizer @@ -64,6 +64,7 @@ __clang__ # pragma GCC diagnostic ignored "-Wmacro-redefined" # pragma GCC diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers" # pragma GCC diagnostic ignored "-Wpointer-bool-conversion" +# pragma GCC diagnostic ignored "-Wconstant-conversion" #endif #if defined(_MSC_VER) diff --git a/lib/posix/epoll.nim b/lib/posix/epoll.nim index 276dd812d..86b977576 100644 --- a/lib/posix/epoll.nim +++ b/lib/posix/epoll.nim @@ -38,8 +38,10 @@ type epoll_data* {.importc: "union epoll_data", header: "<sys/epoll.h>", pure, final.} = object # TODO: This is actually a union. #thePtr* {.importc: "ptr".}: pointer - fd* {.importc: "fd".}: cint # \ - #u32*: uint32 + fd* {.importc: "fd".}: cint + when defined(linux) and defined(amd64): + u32: uint32 # this field ensures that binary size is right - it cannot be + # used because its offset is wrong #u64*: uint64 epoll_event* {.importc: "struct epoll_event", header: "<sys/epoll.h>", pure, final.} = object diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index 1ff861534..02312a4d5 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -27,23 +27,13 @@ ## resulting C code will just ``#include <XYZ.h>`` and *not* define the ## symbols declared here. -{.deadCodeElim:on.} - -from times import Time - -const - hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays - hasAioH = defined(linux) - -when defined(linux): - # On Linux: - # timer_{create,delete,settime,gettime}, - # clock_{getcpuclockid, getres, gettime, nanosleep, settime} lives in librt - {.passL: "-lrt".} -when defined(solaris): - # On Solaris hstrerror lives in libresolv - {.passL: "-lresolv".} +# This 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 actualy try to use the missing declaration +{.deadCodeElim: on.} +# 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: const C_IRUSR = 0c000400 ## Read by owner. @@ -89,1536 +79,12 @@ const DT_SOCK* = 12 ## UNIX domain socket. DT_WHT* = 14 -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 - Timespec* {.importc: "struct timespec", - header: "<time.h>", final, pure.} = object ## struct timespec - tv_sec*: Time ## Seconds. - tv_nsec*: int ## Nanoseconds. - - Dirent* {.importc: "struct dirent", - header: "<dirent.h>", final, pure.} = object ## dirent_t struct - d_ino*: Ino ## File serial number. - when defined(dragonfly): - # DragonflyBSD doesn't have `d_reclen` field. - d_type*: uint8 - elif defined(linux) or defined(macosx) or defined(freebsd) or - defined(netbsd) or defined(openbsd): - d_reclen*: cshort ## Length of this record. (not POSIX) - 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_name*: array[0..255, char] ## Name of entry. - - Tflock* {.importc: "struct flock", final, pure, - header: "<fcntl.h>".} = object ## flock type - l_type*: cshort ## Type of lock; F_RDLCK, F_WRLCK, F_UNLCK. - l_whence*: cshort ## Flag for starting offset. - l_start*: Off ## Relative offset in bytes. - l_len*: Off ## Size; if 0 then until EOF. - l_pid*: Pid ## Process ID of the process holding the lock; - ## returned with F_GETLK. - - FTW* {.importc: "struct FTW", header: "<ftw.h>", final, pure.} = object - base*: cint - level*: cint - - Glob* {.importc: "glob_t", header: "<glob.h>", - final, pure.} = object ## glob_t - gl_pathc*: int ## Count of paths matched by pattern. - gl_pathv*: cstringArray ## Pointer to a list of matched pathnames. - gl_offs*: int ## Slots to reserve at the beginning of gl_pathv. - - Group* {.importc: "struct group", header: "<grp.h>", - final, pure.} = object ## struct group - gr_name*: cstring ## The name of the group. - gr_gid*: Gid ## Numerical group ID. - gr_mem*: cstringArray ## Pointer to a null-terminated array of character - ## pointers to member names. - - Iconv* {.importc: "iconv_t", header: "<iconv.h>", final, pure.} = - object ## Identifies the conversion from one codeset to another. - - Lconv* {.importc: "struct lconv", header: "<locale.h>", final, - pure.} = object - currency_symbol*: cstring - decimal_point*: cstring - frac_digits*: char - grouping*: cstring - int_curr_symbol*: cstring - int_frac_digits*: char - int_n_cs_precedes*: char - int_n_sep_by_space*: char - int_n_sign_posn*: char - int_p_cs_precedes*: char - int_p_sep_by_space*: char - int_p_sign_posn*: char - mon_decimal_point*: cstring - mon_grouping*: cstring - mon_thousands_sep*: cstring - negative_sign*: cstring - n_cs_precedes*: char - n_sep_by_space*: char - n_sign_posn*: char - positive_sign*: cstring - p_cs_precedes*: char - p_sep_by_space*: char - p_sign_posn*: char - thousands_sep*: cstring - - Mqd* {.importc: "mqd_t", header: "<mqueue.h>", final, pure.} = object - MqAttr* {.importc: "struct mq_attr", - header: "<mqueue.h>", - final, pure.} = object ## message queue attribute - mq_flags*: int ## Message queue flags. - mq_maxmsg*: int ## Maximum number of messages. - mq_msgsize*: int ## Maximum message size. - mq_curmsgs*: int ## Number of messages currently queued. - - Passwd* {.importc: "struct passwd", header: "<pwd.h>", - final, pure.} = object ## struct passwd - pw_name*: cstring ## User's login name. - pw_uid*: Uid ## Numerical user ID. - pw_gid*: Gid ## Numerical group ID. - pw_dir*: cstring ## Initial working directory. - pw_shell*: cstring ## Program to use as shell. - - Blkcnt* {.importc: "blkcnt_t", header: "<sys/types.h>".} = int - ## used for file block counts - Blksize* {.importc: "blksize_t", header: "<sys/types.h>".} = int - ## used for block sizes - Clock* {.importc: "clock_t", header: "<sys/types.h>".} = int - ClockId* {.importc: "clockid_t", header: "<sys/types.h>".} = int - Dev* {.importc: "dev_t", header: "<sys/types.h>".} = int - Fsblkcnt* {.importc: "fsblkcnt_t", header: "<sys/types.h>".} = int - Fsfilcnt* {.importc: "fsfilcnt_t", header: "<sys/types.h>".} = int - Gid* {.importc: "gid_t", header: "<sys/types.h>".} = int - 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 - 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>".} = int - Pthread_attr* {.importc: "pthread_attr_t", header: "<sys/types.h>".} = int - Pthread_barrier* {.importc: "pthread_barrier_t", - header: "<sys/types.h>".} = int - Pthread_barrierattr* {.importc: "pthread_barrierattr_t", - header: "<sys/types.h>".} = int - Pthread_cond* {.importc: "pthread_cond_t", header: "<sys/types.h>".} = int - Pthread_condattr* {.importc: "pthread_condattr_t", - header: "<sys/types.h>".} = int - Pthread_key* {.importc: "pthread_key_t", header: "<sys/types.h>".} = int - Pthread_mutex* {.importc: "pthread_mutex_t", header: "<sys/types.h>".} = int - Pthread_mutexattr* {.importc: "pthread_mutexattr_t", - header: "<sys/types.h>".} = int - Pthread_once* {.importc: "pthread_once_t", header: "<sys/types.h>".} = int - Pthread_rwlock* {.importc: "pthread_rwlock_t", - header: "<sys/types.h>".} = int - Pthread_rwlockattr* {.importc: "pthread_rwlockattr_t", - header: "<sys/types.h>".} = int - Pthread_spinlock* {.importc: "pthread_spinlock_t", - header: "<sys/types.h>".} = int - Pthread* {.importc: "pthread_t", header: "<sys/types.h>".} = int - Suseconds* {.importc: "suseconds_t", header: "<sys/types.h>".} = int - #Ttime* {.importc: "time_t", header: "<sys/types.h>".} = int - Timer* {.importc: "timer_t", header: "<sys/types.h>".} = int - Trace_attr* {.importc: "trace_attr_t", header: "<sys/types.h>".} = int - Trace_event_id* {.importc: "trace_event_id_t", - header: "<sys/types.h>".} = int - Trace_event_set* {.importc: "trace_event_set_t", - header: "<sys/types.h>".} = int - Trace_id* {.importc: "trace_id_t", header: "<sys/types.h>".} = int - Uid* {.importc: "uid_t", header: "<sys/types.h>".} = int - Useconds* {.importc: "useconds_t", header: "<sys/types.h>".} = int - - Utsname* {.importc: "struct utsname", - header: "<sys/utsname.h>", - final, pure.} = object ## struct utsname - sysname*, ## Name of this implementation of the operating system. - nodename*, ## Name of this node within the communications - ## network to which this node is attached, if any. - release*, ## Current release level of this implementation. - version*, ## Current version level of this release. - machine*: array[0..255, char] ## Name of the hardware type on which the - ## system is running. - - Sem* {.importc: "sem_t", header: "<semaphore.h>", final, pure.} = object - Ipc_perm* {.importc: "struct ipc_perm", - header: "<sys/ipc.h>", final, pure.} = object ## struct ipc_perm - uid*: Uid ## Owner's user ID. - gid*: Gid ## Owner's group ID. - cuid*: Uid ## Creator's user ID. - cgid*: Gid ## Creator's group ID. - mode*: Mode ## Read/write permission. - - Stat* {.importc: "struct stat", - header: "<sys/stat.h>", final, pure.} = object ## struct stat - st_dev*: Dev ## Device ID of device containing file. - st_ino*: Ino ## File serial number. - st_mode*: Mode ## Mode of file (see below). - st_nlink*: Nlink ## Number of hard links to the file. - st_uid*: Uid ## User ID of file. - st_gid*: Gid ## Group ID of file. - st_rdev*: Dev ## Device ID (if file is character or block special). - st_size*: Off ## For regular files, the file size in bytes. - ## For symbolic links, the length in bytes of the - ## pathname contained in the symbolic link. - ## For a shared memory object, the length in bytes. - ## For a typed memory object, the length in bytes. - ## For other file types, the use of this field is - ## unspecified. - when defined(macosx): - st_atime*: Time ## Time of last access. - st_mtime*: Time ## Time of last data modification. - st_ctime*: Time ## Time of last status change. - else: - st_atim*: Timespec ## Time of last access. - st_mtim*: Timespec ## Time of last data modification. - st_ctim*: Timespec ## Time of last status change. - st_blksize*: Blksize ## A file system-specific preferred I/O block size - ## for this object. In some file system types, this - ## may vary from file to file. - st_blocks*: Blkcnt ## Number of blocks allocated for this object. - - - Statvfs* {.importc: "struct statvfs", header: "<sys/statvfs.h>", - final, pure.} = object ## struct statvfs - f_bsize*: int ## File system block size. - f_frsize*: int ## Fundamental file system block size. - f_blocks*: Fsblkcnt ## Total number of blocks on file system - ## in units of f_frsize. - f_bfree*: Fsblkcnt ## Total number of free blocks. - f_bavail*: Fsblkcnt ## Number of free blocks available to - ## non-privileged process. - f_files*: Fsfilcnt ## Total number of file serial numbers. - f_ffree*: Fsfilcnt ## Total number of free file serial numbers. - f_favail*: Fsfilcnt ## Number of file serial numbers available to - ## non-privileged process. - f_fsid*: int ## File system ID. - f_flag*: int ## Bit mask of f_flag values. - f_namemax*: int ## Maximum filename length. - - Posix_typed_mem_info* {.importc: "struct posix_typed_mem_info", - header: "<sys/mman.h>", final, pure.} = object - posix_tmi_length*: int - - Tm* {.importc: "struct tm", header: "<time.h>", - final, pure.} = object ## struct tm - tm_sec*: cint ## Seconds [0,60]. - tm_min*: cint ## Minutes [0,59]. - tm_hour*: cint ## Hour [0,23]. - tm_mday*: cint ## Day of month [1,31]. - tm_mon*: cint ## Month of year [0,11]. - tm_year*: cint ## Years since 1900. - tm_wday*: cint ## Day of week [0,6] (Sunday =0). - tm_yday*: cint ## Day of year [0,365]. - tm_isdst*: cint ## Daylight Savings flag. - Itimerspec* {.importc: "struct itimerspec", header: "<time.h>", - final, pure.} = object ## struct itimerspec - it_interval*: Timespec ## Timer period. - it_value*: Timespec ## Timer expiration. - - Sig_atomic* {.importc: "sig_atomic_t", header: "<signal.h>".} = cint - ## Possibly volatile-qualified integer type of an object that can be - ## accessed as an atomic entity, even in the presence of asynchronous - ## interrupts. - Sigset* {.importc: "sigset_t", header: "<signal.h>", final, pure.} = object - - SigEvent* {.importc: "struct sigevent", - header: "<signal.h>", final, pure.} = object ## struct sigevent - sigev_notify*: cint ## Notification 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. - - SigVal* {.importc: "union sigval", - header: "<signal.h>", final, pure.} = object ## struct sigval - sival_ptr*: pointer ## pointer signal value; - ## integer signal value not defined! - Sigaction* {.importc: "struct sigaction", - header: "<signal.h>", final, pure.} = object ## struct sigaction - sa_handler*: proc (x: cint) {.noconv.} ## Pointer to a signal-catching - ## function or one of the macros - ## SIG_IGN or SIG_DFL. - sa_mask*: Sigset ## Set of signals to be blocked during execution of - ## the signal handling function. - sa_flags*: cint ## Special flags. - sa_sigaction*: proc (x: cint, y: ptr SigInfo, z: pointer) {.noconv.} - - Stack* {.importc: "stack_t", - header: "<signal.h>", final, pure.} = object ## stack_t - ss_sp*: pointer ## Stack base or pointer. - ss_size*: int ## Stack size. - ss_flags*: cint ## Flags. - - SigStack* {.importc: "struct sigstack", - header: "<signal.h>", final, pure.} = object ## struct sigstack - ss_onstack*: cint ## Non-zero when signal stack is in use. - ss_sp*: pointer ## Signal stack pointer. - - SigInfo* {.importc: "siginfo_t", - header: "<signal.h>", final, pure.} = object ## siginfo_t - si_signo*: cint ## Signal number. - si_code*: cint ## Signal code. - si_errno*: cint ## If non-zero, an errno value associated with - ## this signal, as defined in <errno.h>. - si_pid*: Pid ## Sending process ID. - si_uid*: Uid ## Real user ID of sending process. - si_addr*: pointer ## Address of faulting instruction. - si_status*: cint ## Exit value or signal. - si_band*: int ## Band event for SIGPOLL. - si_value*: SigVal ## Signal value. - - Nl_item* {.importc: "nl_item", header: "<nl_types.h>".} = cint - Nl_catd* {.importc: "nl_catd", header: "<nl_types.h>".} = cint - - Sched_param* {.importc: "struct sched_param", - header: "<sched.h>", - final, pure.} = object ## struct sched_param - sched_priority*: cint - sched_ss_low_priority*: cint ## Low scheduling priority for - ## sporadic server. - sched_ss_repl_period*: Timespec ## Replenishment period for - ## sporadic server. - sched_ss_init_budget*: Timespec ## Initial budget for sporadic server. - sched_ss_max_repl*: cint ## Maximum pending replenishments for - ## sporadic server. - - Timeval* {.importc: "struct timeval", header: "<sys/select.h>", - final, pure.} = object ## struct timeval - tv_sec*: int ## Seconds. - tv_usec*: int ## Microseconds. - TFdSet* {.importc: "fd_set", header: "<sys/select.h>", - final, pure.} = object - Mcontext* {.importc: "mcontext_t", header: "<ucontext.h>", - final, pure.} = object - Ucontext* {.importc: "ucontext_t", header: "<ucontext.h>", - final, pure.} = object ## ucontext_t - uc_link*: ptr Ucontext ## Pointer to the context that is resumed - ## when this context returns. - uc_sigmask*: Sigset ## The set of signals that are blocked when this - ## context is active. - 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>", - final, pure.} = object ## struct aiocb - aio_fildes*: cint ## File descriptor. - aio_offset*: Off ## File offset. - aio_buf*: pointer ## Location of buffer. - aio_nbytes*: int ## Length of transfer. - aio_reqprio*: cint ## Request priority offset. - aio_sigevent*: SigEvent ## Signal number and value. - aio_lio_opcode: cint ## Operation to be performed. +# Platform specific stuff -when hasSpawnH: - type - Tposix_spawnattr* {.importc: "posix_spawnattr_t", - header: "<spawn.h>", final, pure.} = object - Tposix_spawn_file_actions* {.importc: "posix_spawn_file_actions_t", - header: "<spawn.h>", final, pure.} = object - -when defined(linux): - # from sys/un.h - const Sockaddr_un_path_length* = 108 +when defined(linux) and defined(amd64): + include posix_linux_amd64 else: - # 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 - - 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_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 - - Sockaddr_storage* {.importc: "struct sockaddr_storage", - header: "<sys/socket.h>", - pure, final.} = object ## struct sockaddr_storage - ss_family*: TSa_Family ## Address family. - - Tif_nameindex* {.importc: "struct if_nameindex", final, - pure, header: "<net/if.h>".} = object ## struct if_nameindex - if_index*: cint ## Numeric index of the interface. - if_name*: cstring ## Null-terminated name of the interface. - - - 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. - - 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_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_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_level*: cint ## Originating protocol. - cmsg_type*: cint ## Protocol-specific type. - - TLinger* {.importc: "struct linger", pure, final, - header: "<sys/socket.h>".} = object ## struct linger - l_onoff*: cint ## Indicates whether linger option is enabled. - l_linger*: cint ## Linger time, in seconds. - - InPort* = uint16 - InAddrScalar* = uint32 - - InAddrT* {.importc: "in_addr_t", pure, final, - header: "<netinet/in.h>".} = uint32 - - InAddr* {.importc: "struct in_addr", pure, final, - header: "<netinet/in.h>".} = object ## struct in_addr - s_addr*: InAddrScalar - - Sockaddr_in* {.importc: "struct sockaddr_in", pure, final, - header: "<netinet/in.h>".} = object ## struct sockaddr_in - sin_family*: TSa_Family ## AF_INET. - sin_port*: InPort ## Port number. - sin_addr*: InAddr ## IP address. - - In6Addr* {.importc: "struct in6_addr", pure, final, - header: "<netinet/in.h>".} = object ## struct in6_addr - s6_addr*: array[0..15, char] - - Sockaddr_in6* {.importc: "struct sockaddr_in6", pure, final, - header: "<netinet/in.h>".} = object ## struct sockaddr_in6 - sin6_family*: TSa_Family ## AF_INET6. - sin6_port*: InPort ## Port number. - sin6_flowinfo*: int32 ## IPv6 traffic class and flow information. - sin6_addr*: In6Addr ## IPv6 address. - sin6_scope_id*: int32 ## Set of interfaces for a scope. - - Tipv6_mreq* {.importc: "struct ipv6_mreq", pure, final, - header: "<netinet/in.h>".} = object ## struct ipv6_mreq - ipv6mr_multiaddr*: In6Addr ## IPv6 multicast address. - ipv6mr_interface*: cint ## Interface index. - - Hostent* {.importc: "struct hostent", pure, final, - header: "<netdb.h>".} = object ## struct hostent - h_name*: cstring ## Official name of the host. - h_aliases*: cstringArray ## A pointer to an array of pointers to - ## alternative host names, terminated by a - ## null pointer. - h_addrtype*: cint ## Address type. - h_length*: cint ## The length, in bytes, of the address. - h_addr_list*: cstringArray ## A pointer to an array of pointers to network - ## addresses (in network byte order) for the - ## host, terminated by a null pointer. - - Tnetent* {.importc: "struct netent", pure, final, - header: "<netdb.h>".} = object ## struct netent - n_name*: cstring ## Official, fully-qualified (including the - ## domain) name of the host. - n_aliases*: cstringArray ## A pointer to an array of pointers to - ## alternative network names, terminated by a - ## null pointer. - n_addrtype*: cint ## The address type of the network. - n_net*: int32 ## The network number, in host byte order. - - Protoent* {.importc: "struct protoent", pure, final, - header: "<netdb.h>".} = object ## struct protoent - p_name*: cstring ## Official name of the protocol. - p_aliases*: cstringArray ## A pointer to an array of pointers to - ## alternative protocol names, terminated by - ## a null pointer. - p_proto*: cint ## The protocol number. - - Servent* {.importc: "struct servent", pure, final, - header: "<netdb.h>".} = object ## struct servent - s_name*: cstring ## Official name of the service. - s_aliases*: cstringArray ## A pointer to an array of pointers to - ## alternative service names, terminated by - ## a null pointer. - s_port*: cint ## The port number at which the service - ## resides, in network byte order. - s_proto*: cstring ## The name of the protocol to use when - ## contacting the service. - - AddrInfo* {.importc: "struct addrinfo", pure, final, - header: "<netdb.h>".} = object ## struct addrinfo - ai_flags*: cint ## Input flags. - 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_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].} - -var - errno* {.importc, header: "<errno.h>".}: cint ## error variable - h_errno* {.importc, header: "<netdb.h>".}: cint - daylight* {.importc, header: "<time.h>".}: cint - timezone* {.importc, header: "<time.h>".}: int - -# Constants as variables: -when hasAioH: - var - AIO_ALLDONE* {.importc, header: "<aio.h>".}: cint - ## A return value indicating that none of the requested operations - ## could be canceled since they are already complete. - AIO_CANCELED* {.importc, header: "<aio.h>".}: cint - ## A return value indicating that all requested operations have - ## been canceled. - AIO_NOTCANCELED* {.importc, header: "<aio.h>".}: cint - ## A return value indicating that some of the requested operations could - ## not be canceled since they are in progress. - LIO_NOP* {.importc, header: "<aio.h>".}: cint - ## A lio_listio() element operation option indicating that no transfer is - ## requested. - LIO_NOWAIT* {.importc, header: "<aio.h>".}: cint - ## A lio_listio() synchronization operation indicating that the calling - ## thread is to continue execution while the lio_listio() operation is - ## being performed, and no notification is given when the operation is - ## complete. - LIO_READ* {.importc, header: "<aio.h>".}: cint - ## A lio_listio() element operation option requesting a read. - LIO_WAIT* {.importc, header: "<aio.h>".}: cint - ## A lio_listio() synchronization operation indicating that the calling - ## thread is to suspend until the lio_listio() operation is complete. - LIO_WRITE* {.importc, header: "<aio.h>".}: cint - ## A lio_listio() element operation option requesting a write. - -var - RTLD_LAZY* {.importc, header: "<dlfcn.h>".}: cint - ## Relocations are performed at an implementation-defined time. - RTLD_NOW* {.importc, header: "<dlfcn.h>".}: cint - ## Relocations are performed when the object is loaded. - RTLD_GLOBAL* {.importc, header: "<dlfcn.h>".}: cint - ## All symbols are available for relocation processing of other modules. - RTLD_LOCAL* {.importc, header: "<dlfcn.h>".}: cint - ## All symbols are not made available for relocation processing by - ## other modules. - - E2BIG* {.importc, header: "<errno.h>".}: cint - ## Argument list too long. - EACCES* {.importc, header: "<errno.h>".}: cint - ## Permission denied. - EADDRINUSE* {.importc, header: "<errno.h>".}: cint - ## Address in use. - EADDRNOTAVAIL* {.importc, header: "<errno.h>".}: cint - ## Address not available. - EAFNOSUPPORT* {.importc, header: "<errno.h>".}: cint - ## Address family not supported. - EAGAIN* {.importc, header: "<errno.h>".}: cint - ## Resource unavailable, try again (may be the same value as EWOULDBLOCK). - EALREADY* {.importc, header: "<errno.h>".}: cint - ## Connection already in progress. - EBADF* {.importc, header: "<errno.h>".}: cint - ## Bad file descriptor. - EBADMSG* {.importc, header: "<errno.h>".}: cint - ## Bad message. - EBUSY* {.importc, header: "<errno.h>".}: cint - ## Device or resource busy. - ECANCELED* {.importc, header: "<errno.h>".}: cint - ## Operation canceled. - ECHILD* {.importc, header: "<errno.h>".}: cint - ## No child processes. - ECONNABORTED* {.importc, header: "<errno.h>".}: cint - ## Connection aborted. - ECONNREFUSED* {.importc, header: "<errno.h>".}: cint - ## Connection refused. - ECONNRESET* {.importc, header: "<errno.h>".}: cint - ## Connection reset. - EDEADLK* {.importc, header: "<errno.h>".}: cint - ## Resource deadlock would occur. - EDESTADDRREQ* {.importc, header: "<errno.h>".}: cint - ## Destination address required. - EDOM* {.importc, header: "<errno.h>".}: cint - ## Mathematics argument out of domain of function. - EDQUOT* {.importc, header: "<errno.h>".}: cint - ## Reserved. - EEXIST* {.importc, header: "<errno.h>".}: cint - ## File exists. - EFAULT* {.importc, header: "<errno.h>".}: cint - ## Bad address. - EFBIG* {.importc, header: "<errno.h>".}: cint - ## File too large. - EHOSTUNREACH* {.importc, header: "<errno.h>".}: cint - ## Host is unreachable. - EIDRM* {.importc, header: "<errno.h>".}: cint - ## Identifier removed. - EILSEQ* {.importc, header: "<errno.h>".}: cint - ## Illegal byte sequence. - EINPROGRESS* {.importc, header: "<errno.h>".}: cint - ## Operation in progress. - EINTR* {.importc, header: "<errno.h>".}: cint - ## Interrupted function. - EINVAL* {.importc, header: "<errno.h>".}: cint - ## Invalid argument. - EIO* {.importc, header: "<errno.h>".}: cint - ## I/O error. - EISCONN* {.importc, header: "<errno.h>".}: cint - ## Socket is connected. - EISDIR* {.importc, header: "<errno.h>".}: cint - ## Is a directory. - ELOOP* {.importc, header: "<errno.h>".}: cint - ## Too many levels of symbolic links. - EMFILE* {.importc, header: "<errno.h>".}: cint - ## Too many open files. - EMLINK* {.importc, header: "<errno.h>".}: cint - ## Too many links. - EMSGSIZE* {.importc, header: "<errno.h>".}: cint - ## Message too large. - EMULTIHOP* {.importc, header: "<errno.h>".}: cint - ## Reserved. - ENAMETOOLONG* {.importc, header: "<errno.h>".}: cint - ## Filename too long. - ENETDOWN* {.importc, header: "<errno.h>".}: cint - ## Network is down. - ENETRESET* {.importc, header: "<errno.h>".}: cint - ## Connection aborted by network. - ENETUNREACH* {.importc, header: "<errno.h>".}: cint - ## Network unreachable. - ENFILE* {.importc, header: "<errno.h>".}: cint - ## Too many files open in system. - ENOBUFS* {.importc, header: "<errno.h>".}: cint - ## No buffer space available. - ENODATA* {.importc, header: "<errno.h>".}: cint - ## No message is available on the STREAM head read queue. - ENODEV* {.importc, header: "<errno.h>".}: cint - ## No such device. - ENOENT* {.importc, header: "<errno.h>".}: cint - ## No such file or directory. - ENOEXEC* {.importc, header: "<errno.h>".}: cint - ## Executable file format error. - ENOLCK* {.importc, header: "<errno.h>".}: cint - ## No locks available. - ENOLINK* {.importc, header: "<errno.h>".}: cint - ## Reserved. - ENOMEM* {.importc, header: "<errno.h>".}: cint - ## Not enough space. - ENOMSG* {.importc, header: "<errno.h>".}: cint - ## No message of the desired type. - ENOPROTOOPT* {.importc, header: "<errno.h>".}: cint - ## Protocol not available. - ENOSPC* {.importc, header: "<errno.h>".}: cint - ## No space left on device. - ENOSR* {.importc, header: "<errno.h>".}: cint - ## No STREAM resources. - ENOSTR* {.importc, header: "<errno.h>".}: cint - ## Not a STREAM. - ENOSYS* {.importc, header: "<errno.h>".}: cint - ## Function not supported. - ENOTCONN* {.importc, header: "<errno.h>".}: cint - ## The socket is not connected. - ENOTDIR* {.importc, header: "<errno.h>".}: cint - ## Not a directory. - ENOTEMPTY* {.importc, header: "<errno.h>".}: cint - ## Directory not empty. - ENOTSOCK* {.importc, header: "<errno.h>".}: cint - ## Not a socket. - ENOTSUP* {.importc, header: "<errno.h>".}: cint - ## Not supported. - ENOTTY* {.importc, header: "<errno.h>".}: cint - ## Inappropriate I/O control operation. - ENXIO* {.importc, header: "<errno.h>".}: cint - ## No such device or address. - EOPNOTSUPP* {.importc, header: "<errno.h>".}: cint - ## Operation not supported on socket. - EOVERFLOW* {.importc, header: "<errno.h>".}: cint - ## Value too large to be stored in data type. - EPERM* {.importc, header: "<errno.h>".}: cint - ## Operation not permitted. - EPIPE* {.importc, header: "<errno.h>".}: cint - ## Broken pipe. - EPROTO* {.importc, header: "<errno.h>".}: cint - ## Protocol error. - EPROTONOSUPPORT* {.importc, header: "<errno.h>".}: cint - ## Protocol not supported. - EPROTOTYPE* {.importc, header: "<errno.h>".}: cint - ## Protocol wrong type for socket. - ERANGE* {.importc, header: "<errno.h>".}: cint - ## Result too large. - EROFS* {.importc, header: "<errno.h>".}: cint - ## Read-only file system. - ESPIPE* {.importc, header: "<errno.h>".}: cint - ## Invalid seek. - ESRCH* {.importc, header: "<errno.h>".}: cint - ## No such process. - ESTALE* {.importc, header: "<errno.h>".}: cint - ## Reserved. - ETIME* {.importc, header: "<errno.h>".}: cint - ## Stream ioctl() timeout. - ETIMEDOUT* {.importc, header: "<errno.h>".}: cint - ## Connection timed out. - ETXTBSY* {.importc, header: "<errno.h>".}: cint - ## Text file busy. - EWOULDBLOCK* {.importc, header: "<errno.h>".}: cint - ## Operation would block (may be the same value as [EAGAIN]). - EXDEV* {.importc, header: "<errno.h>".}: cint - ## Cross-device link. - - F_DUPFD* {.importc, header: "<fcntl.h>".}: cint - ## Duplicate file descriptor. - F_GETFD* {.importc, header: "<fcntl.h>".}: cint - ## Get file descriptor flags. - F_SETFD* {.importc, header: "<fcntl.h>".}: cint - ## Set file descriptor flags. - F_GETFL* {.importc, header: "<fcntl.h>".}: cint - ## Get file status flags and file access modes. - F_SETFL* {.importc, header: "<fcntl.h>".}: cint - ## Set file status flags. - F_GETLK* {.importc, header: "<fcntl.h>".}: cint - ## Get record locking information. - F_SETLK* {.importc, header: "<fcntl.h>".}: cint - ## Set record locking information. - F_SETLKW* {.importc, header: "<fcntl.h>".}: cint - ## Set record locking information; wait if blocked. - F_GETOWN* {.importc, header: "<fcntl.h>".}: cint - ## Get process or process group ID to receive SIGURG signals. - F_SETOWN* {.importc, header: "<fcntl.h>".}: cint - ## Set process or process group ID to receive SIGURG signals. - FD_CLOEXEC* {.importc, header: "<fcntl.h>".}: cint - ## Close the file descriptor upon execution of an exec family function. - F_RDLCK* {.importc, header: "<fcntl.h>".}: cint - ## Shared or read lock. - F_UNLCK* {.importc, header: "<fcntl.h>".}: cint - ## Unlock. - F_WRLCK* {.importc, header: "<fcntl.h>".}: cint - ## Exclusive or write lock. - O_CREAT* {.importc, header: "<fcntl.h>".}: cint - ## Create file if it does not exist. - O_EXCL* {.importc, header: "<fcntl.h>".}: cint - ## Exclusive use flag. - O_NOCTTY* {.importc, header: "<fcntl.h>".}: cint - ## Do not assign controlling terminal. - O_TRUNC* {.importc, header: "<fcntl.h>".}: cint - ## Truncate flag. - O_APPEND* {.importc, header: "<fcntl.h>".}: cint - ## Set append mode. - O_DSYNC* {.importc, header: "<fcntl.h>".}: cint - ## Write according to synchronized I/O data integrity completion. - O_NONBLOCK* {.importc, header: "<fcntl.h>".}: cint - ## Non-blocking mode. - O_RSYNC* {.importc, header: "<fcntl.h>".}: cint - ## Synchronized read I/O operations. - O_SYNC* {.importc, header: "<fcntl.h>".}: cint - ## Write according to synchronized I/O file integrity completion. - O_ACCMODE* {.importc, header: "<fcntl.h>".}: cint - ## Mask for file access modes. - O_RDONLY* {.importc, header: "<fcntl.h>".}: cint - ## Open for reading only. - O_RDWR* {.importc, header: "<fcntl.h>".}: cint - ## Open for reading and writing. - O_WRONLY* {.importc, header: "<fcntl.h>".}: cint - ## Open for writing only. - POSIX_FADV_NORMAL* {.importc, header: "<fcntl.h>".}: cint - ## The application has no advice to give on its behavior with - ## respect to the specified data. It is the default characteristic - ## if no advice is given for an open file. - POSIX_FADV_SEQUENTIAL* {.importc, header: "<fcntl.h>".}: cint - ## The application expects to access the specified data - # sequentially from lower offsets to higher offsets. - POSIX_FADV_RANDOM* {.importc, header: "<fcntl.h>".}: cint - ## The application expects to access the specified data in a random order. - POSIX_FADV_WILLNEED* {.importc, header: "<fcntl.h>".}: cint - ## The application expects to access the specified data in the near future. - POSIX_FADV_DONTNEED* {.importc, header: "<fcntl.h>".}: cint - ## The application expects that it will not access the specified data - ## in the near future. - POSIX_FADV_NOREUSE* {.importc, header: "<fcntl.h>".}: cint - ## The application expects to access the specified data once and - ## then not reuse it thereafter. - -when not defined(haiku) and not defined(OpenBSD): - var - MM_HARD* {.importc, header: "<fmtmsg.h>".}: cint - ## Source of the condition is hardware. - MM_SOFT* {.importc, header: "<fmtmsg.h>".}: cint - ## Source of the condition is software. - MM_FIRM* {.importc, header: "<fmtmsg.h>".}: cint - ## Source of the condition is firmware. - MM_APPL* {.importc, header: "<fmtmsg.h>".}: cint - ## Condition detected by application. - MM_UTIL* {.importc, header: "<fmtmsg.h>".}: cint - ## Condition detected by utility. - MM_OPSYS* {.importc, header: "<fmtmsg.h>".}: cint - ## Condition detected by operating system. - MM_RECOVER* {.importc, header: "<fmtmsg.h>".}: cint - ## Recoverable error. - MM_NRECOV* {.importc, header: "<fmtmsg.h>".}: cint - ## Non-recoverable error. - MM_HALT* {.importc, header: "<fmtmsg.h>".}: cint - ## Error causing application to halt. - MM_ERROR* {.importc, header: "<fmtmsg.h>".}: cint - ## Application has encountered a non-fatal fault. - MM_WARNING* {.importc, header: "<fmtmsg.h>".}: cint - ## Application has detected unusual non-error condition. - MM_INFO* {.importc, header: "<fmtmsg.h>".}: cint - ## Informative message. - MM_NOSEV* {.importc, header: "<fmtmsg.h>".}: cint - ## No severity level provided for the message. - MM_PRINT* {.importc, header: "<fmtmsg.h>".}: cint - ## Display message on standard error. - MM_CONSOLE* {.importc, header: "<fmtmsg.h>".}: cint - ## Display message on system console. - - MM_OK* {.importc, header: "<fmtmsg.h>".}: cint - ## The function succeeded. - MM_NOTOK* {.importc, header: "<fmtmsg.h>".}: cint - ## The function failed completely. - MM_NOMSG* {.importc, header: "<fmtmsg.h>".}: cint - ## The function was unable to generate a message on standard error, - ## but otherwise succeeded. - MM_NOCON* {.importc, header: "<fmtmsg.h>".}: cint - ## The function was unable to generate a console message, but - ## otherwise succeeded. - -var - FNM_NOMATCH* {.importc, header: "<fnmatch.h>".}: cint - ## The string does not match the specified pattern. - FNM_PATHNAME* {.importc, header: "<fnmatch.h>".}: cint - ## Slash in string only matches slash in pattern. - FNM_PERIOD* {.importc, header: "<fnmatch.h>".}: cint - ## Leading period in string must be exactly matched by period in pattern. - FNM_NOESCAPE* {.importc, header: "<fnmatch.h>".}: cint - ## Disable backslash escaping. - FNM_NOSYS* {.importc, header: "<fnmatch.h>".}: cint - ## Reserved. - - FTW_F* {.importc, header: "<ftw.h>".}: cint - ## File. - FTW_D* {.importc, header: "<ftw.h>".}: cint - ## Directory. - FTW_DNR* {.importc, header: "<ftw.h>".}: cint - ## Directory without read permission. - FTW_DP* {.importc, header: "<ftw.h>".}: cint - ## Directory with subdirectories visited. - FTW_NS* {.importc, header: "<ftw.h>".}: cint - ## Unknown type; stat() failed. - FTW_SL* {.importc, header: "<ftw.h>".}: cint - ## Symbolic link. - FTW_SLN* {.importc, header: "<ftw.h>".}: cint - ## Symbolic link that names a nonexistent file. - - FTW_PHYS* {.importc, header: "<ftw.h>".}: cint - ## Physical walk, does not follow symbolic links. Otherwise, nftw() - ## follows links but does not walk down any path that crosses itself. - FTW_MOUNT* {.importc, header: "<ftw.h>".}: cint - ## The walk does not cross a mount point. - FTW_DEPTH* {.importc, header: "<ftw.h>".}: cint - ## All subdirectories are visited before the directory itself. - FTW_CHDIR* {.importc, header: "<ftw.h>".}: cint - ## The walk changes to each directory before reading it. - - GLOB_APPEND* {.importc, header: "<glob.h>".}: cint - ## Append generated pathnames to those previously obtained. - GLOB_DOOFFS* {.importc, header: "<glob.h>".}: cint - ## Specify how many null pointers to add to the beginning of gl_pathv. - GLOB_ERR* {.importc, header: "<glob.h>".}: cint - ## Cause glob() to return on error. - GLOB_MARK* {.importc, header: "<glob.h>".}: cint - ## Each pathname that is a directory that matches pattern has a - ## slash appended. - GLOB_NOCHECK* {.importc, header: "<glob.h>".}: cint - ## If pattern does not match any pathname, then return a list - ## consisting of only pattern. - GLOB_NOESCAPE* {.importc, header: "<glob.h>".}: cint - ## Disable backslash escaping. - GLOB_NOSORT* {.importc, header: "<glob.h>".}: cint - ## Do not sort the pathnames returned. - GLOB_ABORTED* {.importc, header: "<glob.h>".}: cint - ## The scan was stopped because GLOB_ERR was set or errfunc() - ## returned non-zero. - GLOB_NOMATCH* {.importc, header: "<glob.h>".}: cint - ## The pattern does not match any existing pathname, and GLOB_NOCHECK - ## was not set in flags. - GLOB_NOSPACE* {.importc, header: "<glob.h>".}: cint - ## An attempt to allocate memory failed. - GLOB_NOSYS* {.importc, header: "<glob.h>".}: cint - ## Reserved - - CODESET* {.importc, header: "<langinfo.h>".}: cint - ## Codeset name. - D_T_FMT* {.importc, header: "<langinfo.h>".}: cint - ## String for formatting date and time. - D_FMT * {.importc, header: "<langinfo.h>".}: cint - ## Date format string. - T_FMT* {.importc, header: "<langinfo.h>".}: cint - ## Time format string. - T_FMT_AMPM* {.importc, header: "<langinfo.h>".}: cint - ## a.m. or p.m. time format string. - AM_STR* {.importc, header: "<langinfo.h>".}: cint - ## Ante-meridiem affix. - PM_STR* {.importc, header: "<langinfo.h>".}: cint - ## Post-meridiem affix. - DAY_1* {.importc, header: "<langinfo.h>".}: cint - ## Name of the first day of the week (for example, Sunday). - DAY_2* {.importc, header: "<langinfo.h>".}: cint - ## Name of the second day of the week (for example, Monday). - DAY_3* {.importc, header: "<langinfo.h>".}: cint - ## Name of the third day of the week (for example, Tuesday). - DAY_4* {.importc, header: "<langinfo.h>".}: cint - ## Name of the fourth day of the week (for example, Wednesday). - DAY_5* {.importc, header: "<langinfo.h>".}: cint - ## Name of the fifth day of the week (for example, Thursday). - DAY_6* {.importc, header: "<langinfo.h>".}: cint - ## Name of the sixth day of the week (for example, Friday). - DAY_7* {.importc, header: "<langinfo.h>".}: cint - ## Name of the seventh day of the week (for example, Saturday). - ABDAY_1* {.importc, header: "<langinfo.h>".}: cint - ## Abbreviated name of the first day of the week. - ABDAY_2* {.importc, header: "<langinfo.h>".}: cint - ABDAY_3* {.importc, header: "<langinfo.h>".}: cint - ABDAY_4* {.importc, header: "<langinfo.h>".}: cint - ABDAY_5* {.importc, header: "<langinfo.h>".}: cint - ABDAY_6* {.importc, header: "<langinfo.h>".}: cint - ABDAY_7* {.importc, header: "<langinfo.h>".}: cint - MON_1* {.importc, header: "<langinfo.h>".}: cint - ## Name of the first month of the year. - MON_2* {.importc, header: "<langinfo.h>".}: cint - MON_3* {.importc, header: "<langinfo.h>".}: cint - MON_4* {.importc, header: "<langinfo.h>".}: cint - MON_5* {.importc, header: "<langinfo.h>".}: cint - MON_6* {.importc, header: "<langinfo.h>".}: cint - MON_7* {.importc, header: "<langinfo.h>".}: cint - MON_8* {.importc, header: "<langinfo.h>".}: cint - MON_9* {.importc, header: "<langinfo.h>".}: cint - MON_10* {.importc, header: "<langinfo.h>".}: cint - MON_11* {.importc, header: "<langinfo.h>".}: cint - MON_12* {.importc, header: "<langinfo.h>".}: cint - ABMON_1* {.importc, header: "<langinfo.h>".}: cint - ## Abbreviated name of the first month. - ABMON_2* {.importc, header: "<langinfo.h>".}: cint - ABMON_3* {.importc, header: "<langinfo.h>".}: cint - ABMON_4* {.importc, header: "<langinfo.h>".}: cint - ABMON_5* {.importc, header: "<langinfo.h>".}: cint - ABMON_6* {.importc, header: "<langinfo.h>".}: cint - ABMON_7* {.importc, header: "<langinfo.h>".}: cint - ABMON_8* {.importc, header: "<langinfo.h>".}: cint - ABMON_9* {.importc, header: "<langinfo.h>".}: cint - ABMON_10* {.importc, header: "<langinfo.h>".}: cint - ABMON_11* {.importc, header: "<langinfo.h>".}: cint - ABMON_12* {.importc, header: "<langinfo.h>".}: cint - ERA* {.importc, header: "<langinfo.h>".}: cint - ## Era description segments. - ERA_D_FMT* {.importc, header: "<langinfo.h>".}: cint - ## Era date format string. - ERA_D_T_FMT* {.importc, header: "<langinfo.h>".}: cint - ## Era date and time format string. - ERA_T_FMT* {.importc, header: "<langinfo.h>".}: cint - ## Era time format string. - ALT_DIGITS* {.importc, header: "<langinfo.h>".}: cint - ## Alternative symbols for digits. - RADIXCHAR* {.importc, header: "<langinfo.h>".}: cint - ## Radix character. - THOUSEP* {.importc, header: "<langinfo.h>".}: cint - ## Separator for thousands. - YESEXPR* {.importc, header: "<langinfo.h>".}: cint - ## Affirmative response expression. - NOEXPR* {.importc, header: "<langinfo.h>".}: cint - ## Negative response expression. - CRNCYSTR* {.importc, header: "<langinfo.h>".}: cint - ## Local currency symbol, preceded by '-' if the symbol - ## should appear before the value, '+' if the symbol should appear - ## after the value, or '.' if the symbol should replace the radix - ## character. If the local currency symbol is the empty string, - ## implementations may return the empty string ( "" ). - - LC_ALL* {.importc, header: "<locale.h>".}: cint - LC_COLLATE* {.importc, header: "<locale.h>".}: cint - LC_CTYPE* {.importc, header: "<locale.h>".}: cint - LC_MESSAGES* {.importc, header: "<locale.h>".}: cint - LC_MONETARY* {.importc, header: "<locale.h>".}: cint - LC_NUMERIC* {.importc, header: "<locale.h>".}: cint - LC_TIME* {.importc, header: "<locale.h>".}: cint - - PTHREAD_BARRIER_SERIAL_THREAD* {.importc, header: "<pthread.h>".}: cint - PTHREAD_CANCEL_ASYNCHRONOUS* {.importc, header: "<pthread.h>".}: cint - PTHREAD_CANCEL_ENABLE* {.importc, header: "<pthread.h>".}: cint - PTHREAD_CANCEL_DEFERRED* {.importc, header: "<pthread.h>".}: cint - PTHREAD_CANCEL_DISABLE* {.importc, header: "<pthread.h>".}: cint - PTHREAD_CANCELED* {.importc, header: "<pthread.h>".}: cint - PTHREAD_COND_INITIALIZER* {.importc, header: "<pthread.h>".}: cint - PTHREAD_CREATE_DETACHED* {.importc, header: "<pthread.h>".}: cint - PTHREAD_CREATE_JOINABLE* {.importc, header: "<pthread.h>".}: cint - PTHREAD_EXPLICIT_SCHED* {.importc, header: "<pthread.h>".}: cint - PTHREAD_INHERIT_SCHED* {.importc, header: "<pthread.h>".}: cint - PTHREAD_MUTEX_DEFAULT* {.importc, header: "<pthread.h>".}: cint - PTHREAD_MUTEX_ERRORCHECK* {.importc, header: "<pthread.h>".}: cint - PTHREAD_MUTEX_INITIALIZER* {.importc, header: "<pthread.h>".}: cint - PTHREAD_MUTEX_NORMAL* {.importc, header: "<pthread.h>".}: cint - PTHREAD_MUTEX_RECURSIVE* {.importc, header: "<pthread.h>".}: cint - PTHREAD_ONCE_INIT* {.importc, header: "<pthread.h>".}: cint - PTHREAD_PRIO_INHERIT* {.importc, header: "<pthread.h>".}: cint - PTHREAD_PRIO_NONE* {.importc, header: "<pthread.h>".}: cint - PTHREAD_PRIO_PROTECT* {.importc, header: "<pthread.h>".}: cint - PTHREAD_PROCESS_SHARED* {.importc, header: "<pthread.h>".}: cint - PTHREAD_PROCESS_PRIVATE* {.importc, header: "<pthread.h>".}: cint - PTHREAD_SCOPE_PROCESS* {.importc, header: "<pthread.h>".}: cint - PTHREAD_SCOPE_SYSTEM* {.importc, header: "<pthread.h>".}: cint - - POSIX_ASYNC_IO* {.importc: "_POSIX_ASYNC_IO", header: "<unistd.h>".}: cint - POSIX_PRIO_IO* {.importc: "_POSIX_PRIO_IO", header: "<unistd.h>".}: cint - POSIX_SYNC_IO* {.importc: "_POSIX_SYNC_IO", header: "<unistd.h>".}: cint - F_OK* {.importc: "F_OK", header: "<unistd.h>".}: cint - R_OK* {.importc: "R_OK", header: "<unistd.h>".}: cint - W_OK* {.importc: "W_OK", header: "<unistd.h>".}: cint - X_OK* {.importc: "X_OK", header: "<unistd.h>".}: cint - - CS_PATH* {.importc: "_CS_PATH", header: "<unistd.h>".}: cint - CS_POSIX_V6_ILP32_OFF32_CFLAGS* {.importc: "_CS_POSIX_V6_ILP32_OFF32_CFLAGS", - header: "<unistd.h>".}: cint - CS_POSIX_V6_ILP32_OFF32_LDFLAGS* {. - importc: "_CS_POSIX_V6_ILP32_OFF32_LDFLAGS", header: "<unistd.h>".}: cint - CS_POSIX_V6_ILP32_OFF32_LIBS* {.importc: "_CS_POSIX_V6_ILP32_OFF32_LIBS", - header: "<unistd.h>".}: cint - CS_POSIX_V6_ILP32_OFFBIG_CFLAGS* {. - importc: "_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS", header: "<unistd.h>".}: cint - CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS* {. - importc: "_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS", header: "<unistd.h>".}: cint - CS_POSIX_V6_ILP32_OFFBIG_LIBS* {. - importc: "_CS_POSIX_V6_ILP32_OFFBIG_LIBS", header: "<unistd.h>".}: cint - CS_POSIX_V6_LP64_OFF64_CFLAGS* {. - importc: "_CS_POSIX_V6_LP64_OFF64_CFLAGS", header: "<unistd.h>".}: cint - CS_POSIX_V6_LP64_OFF64_LDFLAGS* {. - importc: "_CS_POSIX_V6_LP64_OFF64_LDFLAGS", header: "<unistd.h>".}: cint - CS_POSIX_V6_LP64_OFF64_LIBS* {. - importc: "_CS_POSIX_V6_LP64_OFF64_LIBS", header: "<unistd.h>".}: cint - CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS* {. - importc: "_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS", header: "<unistd.h>".}: cint - CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS* {. - importc: "_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS", header: "<unistd.h>".}: cint - CS_POSIX_V6_LPBIG_OFFBIG_LIBS* {. - importc: "_CS_POSIX_V6_LPBIG_OFFBIG_LIBS", header: "<unistd.h>".}: cint - CS_POSIX_V6_WIDTH_RESTRICTED_ENVS* {. - importc: "_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS", header: "<unistd.h>".}: cint - F_LOCK* {.importc: "F_LOCK", header: "<unistd.h>".}: cint - F_TEST* {.importc: "F_TEST", header: "<unistd.h>".}: cint - F_TLOCK* {.importc: "F_TLOCK", header: "<unistd.h>".}: cint - F_ULOCK* {.importc: "F_ULOCK", header: "<unistd.h>".}: cint - PC_2_SYMLINKS* {.importc: "_PC_2_SYMLINKS", header: "<unistd.h>".}: cint - PC_ALLOC_SIZE_MIN* {.importc: "_PC_ALLOC_SIZE_MIN", - header: "<unistd.h>".}: cint - PC_ASYNC_IO* {.importc: "_PC_ASYNC_IO", header: "<unistd.h>".}: cint - PC_CHOWN_RESTRICTED* {.importc: "_PC_CHOWN_RESTRICTED", - header: "<unistd.h>".}: cint - PC_FILESIZEBITS* {.importc: "_PC_FILESIZEBITS", header: "<unistd.h>".}: cint - PC_LINK_MAX* {.importc: "_PC_LINK_MAX", header: "<unistd.h>".}: cint - PC_MAX_CANON* {.importc: "_PC_MAX_CANON", header: "<unistd.h>".}: cint - - PC_MAX_INPUT*{.importc: "_PC_MAX_INPUT", header: "<unistd.h>".}: cint - PC_NAME_MAX*{.importc: "_PC_NAME_MAX", header: "<unistd.h>".}: cint - PC_NO_TRUNC*{.importc: "_PC_NO_TRUNC", header: "<unistd.h>".}: cint - PC_PATH_MAX*{.importc: "_PC_PATH_MAX", header: "<unistd.h>".}: cint - PC_PIPE_BUF*{.importc: "_PC_PIPE_BUF", header: "<unistd.h>".}: cint - PC_PRIO_IO*{.importc: "_PC_PRIO_IO", header: "<unistd.h>".}: cint - PC_REC_INCR_XFER_SIZE*{.importc: "_PC_REC_INCR_XFER_SIZE", - header: "<unistd.h>".}: cint - PC_REC_MIN_XFER_SIZE*{.importc: "_PC_REC_MIN_XFER_SIZE", - header: "<unistd.h>".}: cint - PC_REC_XFER_ALIGN*{.importc: "_PC_REC_XFER_ALIGN", header: "<unistd.h>".}: cint - PC_SYMLINK_MAX*{.importc: "_PC_SYMLINK_MAX", header: "<unistd.h>".}: cint - PC_SYNC_IO*{.importc: "_PC_SYNC_IO", header: "<unistd.h>".}: cint - PC_VDISABLE*{.importc: "_PC_VDISABLE", header: "<unistd.h>".}: cint - SC_2_C_BIND*{.importc: "_SC_2_C_BIND", header: "<unistd.h>".}: cint - SC_2_C_DEV*{.importc: "_SC_2_C_DEV", header: "<unistd.h>".}: cint - SC_2_CHAR_TERM*{.importc: "_SC_2_CHAR_TERM", header: "<unistd.h>".}: cint - SC_2_FORT_DEV*{.importc: "_SC_2_FORT_DEV", header: "<unistd.h>".}: cint - SC_2_FORT_RUN*{.importc: "_SC_2_FORT_RUN", header: "<unistd.h>".}: cint - SC_2_LOCALEDEF*{.importc: "_SC_2_LOCALEDEF", header: "<unistd.h>".}: cint - SC_2_PBS*{.importc: "_SC_2_PBS", header: "<unistd.h>".}: cint - SC_2_PBS_ACCOUNTING*{.importc: "_SC_2_PBS_ACCOUNTING", - header: "<unistd.h>".}: cint - SC_2_PBS_CHECKPOINT*{.importc: "_SC_2_PBS_CHECKPOINT", - header: "<unistd.h>".}: cint - SC_2_PBS_LOCATE*{.importc: "_SC_2_PBS_LOCATE", header: "<unistd.h>".}: cint - SC_2_PBS_MESSAGE*{.importc: "_SC_2_PBS_MESSAGE", header: "<unistd.h>".}: cint - SC_2_PBS_TRACK*{.importc: "_SC_2_PBS_TRACK", header: "<unistd.h>".}: cint - SC_2_SW_DEV*{.importc: "_SC_2_SW_DEV", header: "<unistd.h>".}: cint - SC_2_UPE*{.importc: "_SC_2_UPE", header: "<unistd.h>".}: cint - SC_2_VERSION*{.importc: "_SC_2_VERSION", header: "<unistd.h>".}: cint - SC_ADVISORY_INFO*{.importc: "_SC_ADVISORY_INFO", header: "<unistd.h>".}: cint - SC_AIO_LISTIO_MAX*{.importc: "_SC_AIO_LISTIO_MAX", header: "<unistd.h>".}: cint - SC_AIO_MAX*{.importc: "_SC_AIO_MAX", header: "<unistd.h>".}: cint - SC_AIO_PRIO_DELTA_MAX*{.importc: "_SC_AIO_PRIO_DELTA_MAX", - header: "<unistd.h>".}: cint - SC_ARG_MAX*{.importc: "_SC_ARG_MAX", header: "<unistd.h>".}: cint - SC_ASYNCHRONOUS_IO*{.importc: "_SC_ASYNCHRONOUS_IO", - header: "<unistd.h>".}: cint - SC_ATEXIT_MAX*{.importc: "_SC_ATEXIT_MAX", header: "<unistd.h>".}: cint - SC_BARRIERS*{.importc: "_SC_BARRIERS", header: "<unistd.h>".}: cint - SC_BC_BASE_MAX*{.importc: "_SC_BC_BASE_MAX", header: "<unistd.h>".}: cint - SC_BC_DIM_MAX*{.importc: "_SC_BC_DIM_MAX", header: "<unistd.h>".}: cint - SC_BC_SCALE_MAX*{.importc: "_SC_BC_SCALE_MAX", header: "<unistd.h>".}: cint - SC_BC_STRING_MAX*{.importc: "_SC_BC_STRING_MAX", header: "<unistd.h>".}: cint - SC_CHILD_MAX*{.importc: "_SC_CHILD_MAX", header: "<unistd.h>".}: cint - SC_CLK_TCK*{.importc: "_SC_CLK_TCK", header: "<unistd.h>".}: cint - SC_CLOCK_SELECTION*{.importc: "_SC_CLOCK_SELECTION", - header: "<unistd.h>".}: cint - SC_COLL_WEIGHTS_MAX*{.importc: "_SC_COLL_WEIGHTS_MAX", - header: "<unistd.h>".}: cint - SC_CPUTIME*{.importc: "_SC_CPUTIME", header: "<unistd.h>".}: cint - SC_DELAYTIMER_MAX*{.importc: "_SC_DELAYTIMER_MAX", header: "<unistd.h>".}: cint - SC_EXPR_NEST_MAX*{.importc: "_SC_EXPR_NEST_MAX", header: "<unistd.h>".}: cint - SC_FSYNC*{.importc: "_SC_FSYNC", header: "<unistd.h>".}: cint - SC_GETGR_R_SIZE_MAX*{.importc: "_SC_GETGR_R_SIZE_MAX", - header: "<unistd.h>".}: cint - SC_GETPW_R_SIZE_MAX*{.importc: "_SC_GETPW_R_SIZE_MAX", - header: "<unistd.h>".}: cint - SC_HOST_NAME_MAX*{.importc: "_SC_HOST_NAME_MAX", header: "<unistd.h>".}: cint - SC_IOV_MAX*{.importc: "_SC_IOV_MAX", header: "<unistd.h>".}: cint - SC_IPV6*{.importc: "_SC_IPV6", header: "<unistd.h>".}: cint - SC_JOB_CONTROL*{.importc: "_SC_JOB_CONTROL", header: "<unistd.h>".}: cint - SC_LINE_MAX*{.importc: "_SC_LINE_MAX", header: "<unistd.h>".}: cint - SC_LOGIN_NAME_MAX*{.importc: "_SC_LOGIN_NAME_MAX", header: "<unistd.h>".}: cint - SC_MAPPED_FILES*{.importc: "_SC_MAPPED_FILES", header: "<unistd.h>".}: cint - SC_MEMLOCK*{.importc: "_SC_MEMLOCK", header: "<unistd.h>".}: cint - SC_MEMLOCK_RANGE*{.importc: "_SC_MEMLOCK_RANGE", header: "<unistd.h>".}: cint - SC_MEMORY_PROTECTION*{.importc: "_SC_MEMORY_PROTECTION", - header: "<unistd.h>".}: cint - SC_MESSAGE_PASSING*{.importc: "_SC_MESSAGE_PASSING", - header: "<unistd.h>".}: cint - SC_MONOTONIC_CLOCK*{.importc: "_SC_MONOTONIC_CLOCK", - header: "<unistd.h>".}: cint - SC_MQ_OPEN_MAX*{.importc: "_SC_MQ_OPEN_MAX", header: "<unistd.h>".}: cint - SC_MQ_PRIO_MAX*{.importc: "_SC_MQ_PRIO_MAX", header: "<unistd.h>".}: cint - SC_NGROUPS_MAX*{.importc: "_SC_NGROUPS_MAX", header: "<unistd.h>".}: cint - SC_OPEN_MAX*{.importc: "_SC_OPEN_MAX", header: "<unistd.h>".}: cint - SC_PAGE_SIZE*{.importc: "_SC_PAGE_SIZE", header: "<unistd.h>".}: cint - SC_PRIORITIZED_IO*{.importc: "_SC_PRIORITIZED_IO", header: "<unistd.h>".}: cint - SC_PRIORITY_SCHEDULING*{.importc: "_SC_PRIORITY_SCHEDULING", - header: "<unistd.h>".}: cint - SC_RAW_SOCKETS*{.importc: "_SC_RAW_SOCKETS", header: "<unistd.h>".}: cint - SC_RE_DUP_MAX*{.importc: "_SC_RE_DUP_MAX", header: "<unistd.h>".}: cint - SC_READER_WRITER_LOCKS*{.importc: "_SC_READER_WRITER_LOCKS", - header: "<unistd.h>".}: cint - SC_REALTIME_SIGNALS*{.importc: "_SC_REALTIME_SIGNALS", - header: "<unistd.h>".}: cint - SC_REGEXP*{.importc: "_SC_REGEXP", header: "<unistd.h>".}: cint - SC_RTSIG_MAX*{.importc: "_SC_RTSIG_MAX", header: "<unistd.h>".}: cint - SC_SAVED_IDS*{.importc: "_SC_SAVED_IDS", header: "<unistd.h>".}: cint - SC_SEM_NSEMS_MAX*{.importc: "_SC_SEM_NSEMS_MAX", header: "<unistd.h>".}: cint - SC_SEM_VALUE_MAX*{.importc: "_SC_SEM_VALUE_MAX", header: "<unistd.h>".}: cint - SC_SEMAPHORES*{.importc: "_SC_SEMAPHORES", header: "<unistd.h>".}: cint - SC_SHARED_MEMORY_OBJECTS*{.importc: "_SC_SHARED_MEMORY_OBJECTS", - header: "<unistd.h>".}: cint - SC_SHELL*{.importc: "_SC_SHELL", header: "<unistd.h>".}: cint - SC_SIGQUEUE_MAX*{.importc: "_SC_SIGQUEUE_MAX", header: "<unistd.h>".}: cint - SC_SPAWN*{.importc: "_SC_SPAWN", header: "<unistd.h>".}: cint - SC_SPIN_LOCKS*{.importc: "_SC_SPIN_LOCKS", header: "<unistd.h>".}: cint - SC_SPORADIC_SERVER*{.importc: "_SC_SPORADIC_SERVER", - header: "<unistd.h>".}: cint - SC_SS_REPL_MAX*{.importc: "_SC_SS_REPL_MAX", header: "<unistd.h>".}: cint - SC_STREAM_MAX*{.importc: "_SC_STREAM_MAX", header: "<unistd.h>".}: cint - SC_SYMLOOP_MAX*{.importc: "_SC_SYMLOOP_MAX", header: "<unistd.h>".}: cint - SC_SYNCHRONIZED_IO*{.importc: "_SC_SYNCHRONIZED_IO", - header: "<unistd.h>".}: cint - SC_THREAD_ATTR_STACKADDR*{.importc: "_SC_THREAD_ATTR_STACKADDR", - header: "<unistd.h>".}: cint - SC_THREAD_ATTR_STACKSIZE*{.importc: "_SC_THREAD_ATTR_STACKSIZE", - header: "<unistd.h>".}: cint - SC_THREAD_CPUTIME*{.importc: "_SC_THREAD_CPUTIME", header: "<unistd.h>".}: cint - SC_THREAD_DESTRUCTOR_ITERATIONS*{.importc: "_SC_THREAD_DESTRUCTOR_ITERATIONS", - header: "<unistd.h>".}: cint - SC_THREAD_KEYS_MAX*{.importc: "_SC_THREAD_KEYS_MAX", - header: "<unistd.h>".}: cint - SC_THREAD_PRIO_INHERIT*{.importc: "_SC_THREAD_PRIO_INHERIT", - header: "<unistd.h>".}: cint - SC_THREAD_PRIO_PROTECT*{.importc: "_SC_THREAD_PRIO_PROTECT", - header: "<unistd.h>".}: cint - SC_THREAD_PRIORITY_SCHEDULING*{.importc: "_SC_THREAD_PRIORITY_SCHEDULING", - header: "<unistd.h>".}: cint - SC_THREAD_PROCESS_SHARED*{.importc: "_SC_THREAD_PROCESS_SHARED", - header: "<unistd.h>".}: cint - SC_THREAD_SAFE_FUNCTIONS*{.importc: "_SC_THREAD_SAFE_FUNCTIONS", - header: "<unistd.h>".}: cint - SC_THREAD_SPORADIC_SERVER*{.importc: "_SC_THREAD_SPORADIC_SERVER", - header: "<unistd.h>".}: cint - SC_THREAD_STACK_MIN*{.importc: "_SC_THREAD_STACK_MIN", - header: "<unistd.h>".}: cint - SC_THREAD_THREADS_MAX*{.importc: "_SC_THREAD_THREADS_MAX", - header: "<unistd.h>".}: cint - SC_THREADS*{.importc: "_SC_THREADS", header: "<unistd.h>".}: cint - SC_TIMEOUTS*{.importc: "_SC_TIMEOUTS", header: "<unistd.h>".}: cint - SC_TIMER_MAX*{.importc: "_SC_TIMER_MAX", header: "<unistd.h>".}: cint - SC_TIMERS*{.importc: "_SC_TIMERS", header: "<unistd.h>".}: cint - SC_TRACE*{.importc: "_SC_TRACE", header: "<unistd.h>".}: cint - SC_TRACE_EVENT_FILTER*{.importc: "_SC_TRACE_EVENT_FILTER", header: "<unistd.h>".}: cint - SC_TRACE_EVENT_NAME_MAX*{.importc: "_SC_TRACE_EVENT_NAME_MAX", header: "<unistd.h>".}: cint - SC_TRACE_INHERIT*{.importc: "_SC_TRACE_INHERIT", header: "<unistd.h>".}: cint - SC_TRACE_LOG*{.importc: "_SC_TRACE_LOG", header: "<unistd.h>".}: cint - SC_TRACE_NAME_MAX*{.importc: "_SC_TRACE_NAME_MAX", header: "<unistd.h>".}: cint - SC_TRACE_SYS_MAX*{.importc: "_SC_TRACE_SYS_MAX", header: "<unistd.h>".}: cint - SC_TRACE_USER_EVENT_MAX*{.importc: "_SC_TRACE_USER_EVENT_MAX", header: "<unistd.h>".}: cint - SC_TTY_NAME_MAX*{.importc: "_SC_TTY_NAME_MAX", header: "<unistd.h>".}: cint - SC_TYPED_MEMORY_OBJECTS*{.importc: "_SC_TYPED_MEMORY_OBJECTS", header: "<unistd.h>".}: cint - SC_TZNAME_MAX*{.importc: "_SC_TZNAME_MAX", header: "<unistd.h>".}: cint - SC_V6_ILP32_OFF32*{.importc: "_SC_V6_ILP32_OFF32", header: "<unistd.h>".}: cint - SC_V6_ILP32_OFFBIG*{.importc: "_SC_V6_ILP32_OFFBIG", header: "<unistd.h>".}: cint - SC_V6_LP64_OFF64*{.importc: "_SC_V6_LP64_OFF64", header: "<unistd.h>".}: cint - SC_V6_LPBIG_OFFBIG*{.importc: "_SC_V6_LPBIG_OFFBIG", header: "<unistd.h>".}: cint - SC_VERSION*{.importc: "_SC_VERSION", header: "<unistd.h>".}: cint - SC_XBS5_ILP32_OFF32*{.importc: "_SC_XBS5_ILP32_OFF32", header: "<unistd.h>".}: cint - SC_XBS5_ILP32_OFFBIG*{.importc: "_SC_XBS5_ILP32_OFFBIG", header: "<unistd.h>".}: cint - SC_XBS5_LP64_OFF64*{.importc: "_SC_XBS5_LP64_OFF64", header: "<unistd.h>".}: cint - SC_XBS5_LPBIG_OFFBIG*{.importc: "_SC_XBS5_LPBIG_OFFBIG", - header: "<unistd.h>".}: cint - SC_XOPEN_CRYPT*{.importc: "_SC_XOPEN_CRYPT", header: "<unistd.h>".}: cint - SC_XOPEN_ENH_I18N*{.importc: "_SC_XOPEN_ENH_I18N", header: "<unistd.h>".}: cint - SC_XOPEN_LEGACY*{.importc: "_SC_XOPEN_LEGACY", header: "<unistd.h>".}: cint - SC_XOPEN_REALTIME*{.importc: "_SC_XOPEN_REALTIME", header: "<unistd.h>".}: cint - SC_XOPEN_REALTIME_THREADS*{.importc: "_SC_XOPEN_REALTIME_THREADS", - header: "<unistd.h>".}: cint - SC_XOPEN_SHM*{.importc: "_SC_XOPEN_SHM", header: "<unistd.h>".}: cint - SC_XOPEN_STREAMS*{.importc: "_SC_XOPEN_STREAMS", header: "<unistd.h>".}: cint - SC_XOPEN_UNIX*{.importc: "_SC_XOPEN_UNIX", header: "<unistd.h>".}: cint - SC_XOPEN_VERSION*{.importc: "_SC_XOPEN_VERSION", header: "<unistd.h>".}: cint - SC_NPROCESSORS_ONLN*{.importc: "_SC_NPROCESSORS_ONLN", - header: "<unistd.h>".}: cint - - SEM_FAILED* {.importc, header: "<semaphore.h>".}: pointer - IPC_CREAT* {.importc, header: "<sys/ipc.h>".}: cint - ## Create entry if key does not exist. - IPC_EXCL* {.importc, header: "<sys/ipc.h>".}: cint - ## Fail if key exists. - IPC_NOWAIT* {.importc, header: "<sys/ipc.h>".}: cint - ## Error if request must wait. - - IPC_PRIVATE* {.importc, header: "<sys/ipc.h>".}: cint - ## Private key. - - IPC_RMID* {.importc, header: "<sys/ipc.h>".}: cint - ## Remove identifier. - IPC_SET* {.importc, header: "<sys/ipc.h>".}: cint - ## Set options. - IPC_STAT* {.importc, header: "<sys/ipc.h>".}: cint - ## Get options. - - S_IFMT* {.importc, header: "<sys/stat.h>".}: cint - ## Type of file. - S_IFBLK* {.importc, header: "<sys/stat.h>".}: cint - ## Block special. - S_IFCHR* {.importc, header: "<sys/stat.h>".}: cint - ## Character special. - S_IFIFO* {.importc, header: "<sys/stat.h>".}: cint - ## FIFO special. - S_IFREG* {.importc, header: "<sys/stat.h>".}: cint - ## Regular. - S_IFDIR* {.importc, header: "<sys/stat.h>".}: cint - ## Directory. - S_IFLNK* {.importc, header: "<sys/stat.h>".}: cint - ## Symbolic link. - S_IFSOCK* {.importc, header: "<sys/stat.h>".}: cint - ## Socket. - S_IRWXU* {.importc, header: "<sys/stat.h>".}: cint - ## Read, write, execute/search by owner. - S_IRUSR* {.importc, header: "<sys/stat.h>".}: cint - ## Read permission, owner. - S_IWUSR* {.importc, header: "<sys/stat.h>".}: cint - ## Write permission, owner. - S_IXUSR* {.importc, header: "<sys/stat.h>".}: cint - ## Execute/search permission, owner. - S_IRWXG* {.importc, header: "<sys/stat.h>".}: cint - ## Read, write, execute/search by group. - S_IRGRP* {.importc, header: "<sys/stat.h>".}: cint - ## Read permission, group. - S_IWGRP* {.importc, header: "<sys/stat.h>".}: cint - ## Write permission, group. - S_IXGRP* {.importc, header: "<sys/stat.h>".}: cint - ## Execute/search permission, group. - S_IRWXO* {.importc, header: "<sys/stat.h>".}: cint - ## Read, write, execute/search by others. - S_IROTH* {.importc, header: "<sys/stat.h>".}: cint - ## Read permission, others. - S_IWOTH* {.importc, header: "<sys/stat.h>".}: cint - ## Write permission, others. - S_IXOTH* {.importc, header: "<sys/stat.h>".}: cint - ## Execute/search permission, others. - S_ISUID* {.importc, header: "<sys/stat.h>".}: cint - ## Set-user-ID on execution. - S_ISGID* {.importc, header: "<sys/stat.h>".}: cint - ## Set-group-ID on execution. - S_ISVTX* {.importc, header: "<sys/stat.h>".}: cint - ## On directories, restricted deletion flag. - - ST_RDONLY* {.importc, header: "<sys/statvfs.h>".}: cint - ## Read-only file system. - ST_NOSUID* {.importc, header: "<sys/statvfs.h>".}: cint - ## Does not support the semantics of the ST_ISUID and ST_ISGID file mode bits. - - PROT_READ* {.importc, header: "<sys/mman.h>".}: cint - ## Page can be read. - PROT_WRITE* {.importc, header: "<sys/mman.h>".}: cint - ## Page can be written. - PROT_EXEC* {.importc, header: "<sys/mman.h>".}: cint - ## Page can be executed. - PROT_NONE* {.importc, header: "<sys/mman.h>".}: cint - ## Page cannot be accessed. - MAP_SHARED* {.importc, header: "<sys/mman.h>".}: cint - ## Share changes. - MAP_PRIVATE* {.importc, header: "<sys/mman.h>".}: cint - ## Changes are private. - MAP_FIXED* {.importc, header: "<sys/mman.h>".}: cint - ## Interpret addr exactly. - MS_ASYNC* {.importc, header: "<sys/mman.h>".}: cint - ## Perform asynchronous writes. - MS_SYNC* {.importc, header: "<sys/mman.h>".}: cint - ## Perform synchronous writes. - MS_INVALIDATE* {.importc, header: "<sys/mman.h>".}: cint - ## Invalidate mappings. - MCL_CURRENT* {.importc, header: "<sys/mman.h>".}: cint - ## Lock currently mapped pages. - MCL_FUTURE* {.importc, header: "<sys/mman.h>".}: cint - ## Lock pages that become mapped. - MAP_FAILED* {.importc, header: "<sys/mman.h>".}: cint - POSIX_MADV_NORMAL* {.importc, header: "<sys/mman.h>".}: cint - ## The application has no advice to give on its behavior with - ## respect to the specified range. It is the default characteristic - ## if no advice is given for a range of memory. - POSIX_MADV_SEQUENTIAL* {.importc, header: "<sys/mman.h>".}: cint - ## The application expects to access the specified range sequentially - ## from lower addresses to higher addresses. - POSIX_MADV_RANDOM* {.importc, header: "<sys/mman.h>".}: cint - ## The application expects to access the specified range in a random order. - POSIX_MADV_WILLNEED* {.importc, header: "<sys/mman.h>".}: cint - ## The application expects to access the specified range in the near future. - POSIX_MADV_DONTNEED* {.importc, header: "<sys/mman.h>".}: cint - POSIX_TYPED_MEM_ALLOCATE* {.importc, header: "<sys/mman.h>".}: cint - POSIX_TYPED_MEM_ALLOCATE_CONTIG* {.importc, header: "<sys/mman.h>".}: cint - POSIX_TYPED_MEM_MAP_ALLOCATABLE* {.importc, header: "<sys/mman.h>".}: cint - - - CLOCKS_PER_SEC* {.importc, header: "<time.h>".}: int - ## A number used to convert the value returned by the clock() function - ## into seconds. - CLOCK_PROCESS_CPUTIME_ID* {.importc, header: "<time.h>".}: cint - ## The identifier of the CPU-time clock associated with the process - ## making a clock() or timer*() function call. - CLOCK_THREAD_CPUTIME_ID* {.importc, header: "<time.h>".}: cint - CLOCK_REALTIME* {.importc, header: "<time.h>".}: cint - ## The identifier of the system-wide realtime clock. - TIMER_ABSTIME* {.importc, header: "<time.h>".}: cint - ## Flag indicating time is absolute. For functions taking timer - ## objects, this refers to the clock associated with the timer. - CLOCK_MONOTONIC* {.importc, header: "<time.h>".}: cint - - WNOHANG* {.importc, header: "<sys/wait.h>".}: cint - ## Do not hang if no status is available; return immediately. - WUNTRACED* {.importc, header: "<sys/wait.h>".}: cint - ## Report status of stopped child process. - WEXITSTATUS* {.importc, header: "<sys/wait.h>".}: cint - ## Return exit status. - WSTOPSIG* {.importc, header: "<sys/wait.h>".}: cint - ## Return signal number that caused process to stop. - WTERMSIG* {.importc, header: "<sys/wait.h>".}: cint - ## Return signal number that caused process to terminate. - WEXITED* {.importc, header: "<sys/wait.h>".}: cint - ## Wait for processes that have exited. - WSTOPPED* {.importc, header: "<sys/wait.h>".}: cint - ## Status is returned for any child that has stopped upon receipt - ## of a signal. - WCONTINUED* {.importc, header: "<sys/wait.h>".}: cint - ## Status is returned for any child that was stopped and has been continued. - WNOWAIT* {.importc, header: "<sys/wait.h>".}: cint - ## Keep the process whose status is returned in infop in a waitable state. - P_ALL* {.importc, header: "<sys/wait.h>".}: cint - P_PID* {.importc, header: "<sys/wait.h>".}: cint - P_PGID* {.importc, header: "<sys/wait.h>".}: cint - - SIG_DFL* {.importc, header: "<signal.h>".}: proc (x: cint) {.noconv.} - ## Request for default signal handling. - SIG_ERR* {.importc, header: "<signal.h>".}: proc (x: cint) {.noconv.} - ## Return value from signal() in case of error. - cSIG_HOLD* {.importc: "SIG_HOLD", - header: "<signal.h>".}: proc (x: cint) {.noconv.} - ## Request that signal be held. - SIG_IGN* {.importc, header: "<signal.h>".}: proc (x: cint) {.noconv.} - ## Request that signal be ignored. - - SIGEV_NONE* {.importc, header: "<signal.h>".}: cint - SIGEV_SIGNAL* {.importc, header: "<signal.h>".}: cint - SIGEV_THREAD* {.importc, header: "<signal.h>".}: cint - SIGABRT* {.importc, header: "<signal.h>".}: cint - SIGALRM* {.importc, header: "<signal.h>".}: cint - SIGBUS* {.importc, header: "<signal.h>".}: cint - SIGCHLD* {.importc, header: "<signal.h>".}: cint - SIGCONT* {.importc, header: "<signal.h>".}: cint - SIGFPE* {.importc, header: "<signal.h>".}: cint - SIGHUP* {.importc, header: "<signal.h>".}: cint - SIGILL* {.importc, header: "<signal.h>".}: cint - SIGINT* {.importc, header: "<signal.h>".}: cint - SIGKILL* {.importc, header: "<signal.h>".}: cint - SIGPIPE* {.importc, header: "<signal.h>".}: cint - SIGQUIT* {.importc, header: "<signal.h>".}: cint - SIGSEGV* {.importc, header: "<signal.h>".}: cint - SIGSTOP* {.importc, header: "<signal.h>".}: cint - SIGTERM* {.importc, header: "<signal.h>".}: cint - SIGTSTP* {.importc, header: "<signal.h>".}: cint - SIGTTIN* {.importc, header: "<signal.h>".}: cint - SIGTTOU* {.importc, header: "<signal.h>".}: cint - SIGUSR1* {.importc, header: "<signal.h>".}: cint - SIGUSR2* {.importc, header: "<signal.h>".}: cint - SIGPOLL* {.importc, header: "<signal.h>".}: cint - SIGPROF* {.importc, header: "<signal.h>".}: cint - SIGSYS* {.importc, header: "<signal.h>".}: cint - SIGTRAP* {.importc, header: "<signal.h>".}: cint - SIGURG* {.importc, header: "<signal.h>".}: cint - SIGVTALRM* {.importc, header: "<signal.h>".}: cint - SIGXCPU* {.importc, header: "<signal.h>".}: cint - SIGXFSZ* {.importc, header: "<signal.h>".}: cint - SA_NOCLDSTOP* {.importc, header: "<signal.h>".}: cint - SIG_BLOCK* {.importc, header: "<signal.h>".}: cint - SIG_UNBLOCK* {.importc, header: "<signal.h>".}: cint - SIG_SETMASK* {.importc, header: "<signal.h>".}: cint - SA_ONSTACK* {.importc, header: "<signal.h>".}: cint - SA_RESETHAND* {.importc, header: "<signal.h>".}: cint - SA_RESTART* {.importc, header: "<signal.h>".}: cint - SA_SIGINFO* {.importc, header: "<signal.h>".}: cint - SA_NOCLDWAIT* {.importc, header: "<signal.h>".}: cint - SA_NODEFER* {.importc, header: "<signal.h>".}: cint - SS_ONSTACK* {.importc, header: "<signal.h>".}: cint - SS_DISABLE* {.importc, header: "<signal.h>".}: cint - MINSIGSTKSZ* {.importc, header: "<signal.h>".}: cint - SIGSTKSZ* {.importc, header: "<signal.h>".}: cint - - NL_SETD* {.importc, header: "<nl_types.h>".}: cint - NL_CAT_LOCALE* {.importc, header: "<nl_types.h>".}: cint - - SCHED_FIFO* {.importc, header: "<sched.h>".}: cint - SCHED_RR* {.importc, header: "<sched.h>".}: cint - SCHED_SPORADIC* {.importc, header: "<sched.h>".}: cint - SCHED_OTHER* {.importc, header: "<sched.h>".}: cint - FD_SETSIZE* {.importc, header: "<sys/select.h>".}: cint - - SEEK_SET* {.importc, header: "<unistd.h>".}: cint - SEEK_CUR* {.importc, header: "<unistd.h>".}: cint - SEEK_END* {.importc, header: "<unistd.h>".}: cint - - SCM_RIGHTS* {.importc, header: "<sys/socket.h>".}: cint - ## Indicates that the data array contains the access rights - ## to be sent or received. - - SOCK_DGRAM* {.importc, header: "<sys/socket.h>".}: cint ## Datagram socket. - SOCK_RAW* {.importc, header: "<sys/socket.h>".}: cint - ## Raw Protocol Interface. - SOCK_SEQPACKET* {.importc, header: "<sys/socket.h>".}: cint - ## Sequenced-packet socket. - SOCK_STREAM* {.importc, header: "<sys/socket.h>".}: cint - ## Byte-stream socket. - - SOL_SOCKET* {.importc, header: "<sys/socket.h>".}: cint - ## Options to be accessed at socket level, not protocol level. - - SO_ACCEPTCONN* {.importc, header: "<sys/socket.h>".}: cint - ## Socket is accepting connections. - SO_BROADCAST* {.importc, header: "<sys/socket.h>".}: cint - ## Transmission of broadcast messages is supported. - SO_DEBUG* {.importc, header: "<sys/socket.h>".}: cint - ## Debugging information is being recorded. - SO_DONTROUTE* {.importc, header: "<sys/socket.h>".}: cint - ## Bypass normal routing. - SO_ERROR* {.importc, header: "<sys/socket.h>".}: cint - ## Socket error status. - SO_KEEPALIVE* {.importc, header: "<sys/socket.h>".}: cint - ## Connections are kept alive with periodic messages. - SO_LINGER* {.importc, header: "<sys/socket.h>".}: cint - ## Socket lingers on close. - SO_OOBINLINE* {.importc, header: "<sys/socket.h>".}: cint - ## Out-of-band data is transmitted in line. - SO_RCVBUF* {.importc, header: "<sys/socket.h>".}: cint - ## Receive buffer size. - SO_RCVLOWAT* {.importc, header: "<sys/socket.h>".}: cint - ## Receive *low water mark*. - SO_RCVTIMEO* {.importc, header: "<sys/socket.h>".}: cint - ## Receive timeout. - SO_REUSEADDR* {.importc, header: "<sys/socket.h>".}: cint - ## Reuse of local addresses is supported. - SO_SNDBUF* {.importc, header: "<sys/socket.h>".}: cint - ## Send buffer size. - SO_SNDLOWAT* {.importc, header: "<sys/socket.h>".}: cint - ## Send *low water mark*. - SO_SNDTIMEO* {.importc, header: "<sys/socket.h>".}: cint - ## Send timeout. - SO_TYPE* {.importc, header: "<sys/socket.h>".}: cint - ## Socket type. - - SOMAXCONN* {.importc, header: "<sys/socket.h>".}: cint - ## The maximum backlog queue length. - - MSG_CTRUNC* {.importc, header: "<sys/socket.h>".}: cint - ## Control data truncated. - MSG_DONTROUTE* {.importc, header: "<sys/socket.h>".}: cint - ## Send without using routing tables. - MSG_EOR* {.importc, header: "<sys/socket.h>".}: cint - ## Terminates a record (if supported by the protocol). - MSG_OOB* {.importc, header: "<sys/socket.h>".}: cint - ## Out-of-band data. + include posix_other when not defined(macosx): proc st_atime*(s: Stat): Time {.inline.} = @@ -1631,224 +97,6 @@ when not defined(macosx): ## Second-granularity time of last status change. result = s.st_ctim.tv_sec -proc WIFCONTINUED*(s:cint) : bool {.importc, header: "<sys/wait.h>".} - ## True if child has been continued. -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>".} - ## True if child exited due to uncaught signal. -proc WIFSTOPPED*(s:cint) : bool {.importc, header: "<sys/wait.h>".} - ## True if child is currently stopped. - -when defined(linux): - var - MAP_POPULATE* {.importc, header: "<sys/mman.h>".}: cint - ## Populate (prefault) page tables for a mapping. -else: - var - MAP_POPULATE*: cint = 0 - -when defined(linux) or defined(nimdoc): - when defined(alpha) or defined(mips) or defined(parisc) or - defined(sparc) 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) -else: - var SO_REUSEPORT* {.importc, header: "<sys/socket.h>".}: cint - -when defined(macosx): - # 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 - const - MSG_NOSIGNAL* = 0'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. - -var - MSG_PEEK* {.importc, header: "<sys/socket.h>".}: cint - ## Leave received data in queue. - MSG_TRUNC* {.importc, header: "<sys/socket.h>".}: cint - ## Normal data truncated. - MSG_WAITALL* {.importc, header: "<sys/socket.h>".}: cint - ## Attempt to fill the read buffer. - - AF_INET* {.importc, header: "<sys/socket.h>".}: cint - ## Internet domain sockets for use with IPv4 addresses. - AF_INET6* {.importc, header: "<sys/socket.h>".}: cint - ## Internet domain sockets for use with IPv6 addresses. - AF_UNIX* {.importc, header: "<sys/socket.h>".}: cint - ## UNIX domain sockets. - AF_UNSPEC* {.importc, header: "<sys/socket.h>".}: cint - ## Unspecified. - - SHUT_RD* {.importc, header: "<sys/socket.h>".}: cint - ## Disables further receive operations. - SHUT_RDWR* {.importc, header: "<sys/socket.h>".}: cint - ## Disables further send and receive operations. - SHUT_WR* {.importc, header: "<sys/socket.h>".}: cint - ## Disables further send operations. - - IF_NAMESIZE* {.importc, header: "<net/if.h>".}: cint - - IPPROTO_IP* {.importc, header: "<netinet/in.h>".}: cint - ## Internet protocol. - IPPROTO_IPV6* {.importc, header: "<netinet/in.h>".}: cint - ## Internet Protocol Version 6. - IPPROTO_ICMP* {.importc, header: "<netinet/in.h>".}: cint - ## Control message protocol. - IPPROTO_RAW* {.importc, header: "<netinet/in.h>".}: cint - ## Raw IP Packets Protocol. - IPPROTO_TCP* {.importc, header: "<netinet/in.h>".}: cint - ## Transmission control protocol. - IPPROTO_UDP* {.importc, header: "<netinet/in.h>".}: cint - ## User datagram protocol. - - INADDR_ANY* {.importc, header: "<netinet/in.h>".}: InAddrScalar - ## IPv4 local host address. - INADDR_LOOPBACK* {.importc, header: "<netinet/in.h>".}: InAddrScalar - ## IPv4 loopback address. - INADDR_BROADCAST* {.importc, header: "<netinet/in.h>".}: InAddrScalar - ## IPv4 broadcast address. - - INET_ADDRSTRLEN* {.importc, header: "<netinet/in.h>".}: cint - ## 16. Length of the string form for IP. - INET6_ADDRSTRLEN* {.importc, header: "<netinet/in.h>".}: cint - ## Length of the string form for IPv6. - - IPV6_JOIN_GROUP* {.importc, header: "<netinet/in.h>".}: cint - ## Join a multicast group. - IPV6_LEAVE_GROUP* {.importc, header: "<netinet/in.h>".}: cint - ## Quit a multicast group. - IPV6_MULTICAST_HOPS* {.importc, header: "<netinet/in.h>".}: cint - ## Multicast hop limit. - IPV6_MULTICAST_IF* {.importc, header: "<netinet/in.h>".}: cint - ## Interface to use for outgoing multicast packets. - IPV6_MULTICAST_LOOP* {.importc, header: "<netinet/in.h>".}: cint - ## Multicast packets are delivered back to the local application. - IPV6_UNICAST_HOPS* {.importc, header: "<netinet/in.h>".}: cint - ## Unicast hop limit. - IPV6_V6ONLY* {.importc, header: "<netinet/in.h>".}: cint - ## Restrict AF_INET6 socket to IPv6 communications only. - - TCP_NODELAY* {.importc, header: "<netinet/tcp.h>".}: cint - ## Avoid coalescing of small segments. - - IPPORT_RESERVED* {.importc, header: "<netdb.h>".}: cint - - HOST_NOT_FOUND* {.importc, header: "<netdb.h>".}: cint - NO_DATA* {.importc, header: "<netdb.h>".}: cint - NO_RECOVERY* {.importc, header: "<netdb.h>".}: cint - TRY_AGAIN* {.importc, header: "<netdb.h>".}: cint - - AI_PASSIVE* {.importc, header: "<netdb.h>".}: cint - ## Socket address is intended for bind(). - AI_CANONNAME* {.importc, header: "<netdb.h>".}: cint - ## Request for canonical name. - AI_NUMERICHOST* {.importc, header: "<netdb.h>".}: cint - ## Return numeric host address as name. - AI_NUMERICSERV* {.importc, header: "<netdb.h>".}: cint - ## Inhibit service name resolution. - AI_V4MAPPED* {.importc, header: "<netdb.h>".}: cint - ## If no IPv6 addresses are found, query for IPv4 addresses and - ## return them to the caller as IPv4-mapped IPv6 addresses. - AI_ALL* {.importc, header: "<netdb.h>".}: cint - ## Query for both IPv4 and IPv6 addresses. - AI_ADDRCONFIG* {.importc, header: "<netdb.h>".}: cint - ## Query for IPv4 addresses only when an IPv4 address is configured; - ## query for IPv6 addresses only when an IPv6 address is configured. - - NI_NOFQDN* {.importc, header: "<netdb.h>".}: cint - ## Only the nodename portion of the FQDN is returned for local hosts. - NI_NUMERICHOST* {.importc, header: "<netdb.h>".}: cint - ## The numeric form of the node's address is returned instead of its name. - NI_NAMEREQD* {.importc, header: "<netdb.h>".}: cint - ## Return an error if the node's name cannot be located in the database. - NI_NUMERICSERV* {.importc, header: "<netdb.h>".}: cint - ## The numeric form of the service address is returned instead of its name. - NI_NUMERICSCOPE* {.importc, header: "<netdb.h>".}: cint - ## For IPv6 addresses, the numeric form of the scope identifier is - ## returned instead of its name. - NI_DGRAM* {.importc, header: "<netdb.h>".}: cint - ## Indicates that the service is a datagram service (SOCK_DGRAM). - - EAI_AGAIN* {.importc, header: "<netdb.h>".}: cint - ## The name could not be resolved at this time. Future attempts may succeed. - EAI_BADFLAGS* {.importc, header: "<netdb.h>".}: cint - ## The flags had an invalid value. - EAI_FAIL* {.importc, header: "<netdb.h>".}: cint - ## A non-recoverable error occurred. - EAI_FAMILY* {.importc, header: "<netdb.h>".}: cint - ## The address family was not recognized or the address length - ## was invalid for the specified family. - EAI_MEMORY* {.importc, header: "<netdb.h>".}: cint - ## There was a memory allocation failure. - EAI_NONAME* {.importc, header: "<netdb.h>".}: cint - ## The name does not resolve for the supplied parameters. - ## NI_NAMEREQD is set and the host's name cannot be located, - ## or both nodename and servname were null. - EAI_SERVICE* {.importc, header: "<netdb.h>".}: cint - ## The service passed was not recognized for the specified socket type. - EAI_SOCKTYPE* {.importc, header: "<netdb.h>".}: cint - ## The intended socket type was not recognized. - EAI_SYSTEM* {.importc, header: "<netdb.h>".}: cint - ## A system error occurred. The error code can be found in errno. - EAI_OVERFLOW* {.importc, header: "<netdb.h>".}: cint - ## An argument buffer overflowed. - - POLLIN* {.importc, header: "<poll.h>".}: cshort - ## Data other than high-priority data may be read without blocking. - POLLRDNORM* {.importc, header: "<poll.h>".}: cshort - ## Normal data may be read without blocking. - POLLRDBAND* {.importc, header: "<poll.h>".}: cshort - ## Priority data may be read without blocking. - POLLPRI* {.importc, header: "<poll.h>".}: cshort - ## High priority data may be read without blocking. - POLLOUT* {.importc, header: "<poll.h>".}: cshort - ## Normal data may be written without blocking. - POLLWRNORM* {.importc, header: "<poll.h>".}: cshort - ## Equivalent to POLLOUT. - POLLWRBAND* {.importc, header: "<poll.h>".}: cshort - ## Priority data may be written. - POLLERR* {.importc, header: "<poll.h>".}: cshort - ## An error has occurred (revents only). - POLLHUP* {.importc, header: "<poll.h>".}: cshort - ## Device has been disconnected (revents only). - POLLNVAL* {.importc, header: "<poll.h>".}: cshort - ## Invalid fd member (revents only). - - -when hasSpawnH: - var - POSIX_SPAWN_RESETIDS* {.importc, header: "<spawn.h>".}: cint - POSIX_SPAWN_SETPGROUP* {.importc, header: "<spawn.h>".}: cint - POSIX_SPAWN_SETSCHEDPARAM* {.importc, header: "<spawn.h>".}: cint - POSIX_SPAWN_SETSCHEDULER* {.importc, header: "<spawn.h>".}: cint - POSIX_SPAWN_SETSIGDEF* {.importc, header: "<spawn.h>".}: cint - POSIX_SPAWN_SETSIGMASK* {.importc, header: "<spawn.h>".}: cint - - when defined(linux): - # better be safe than sorry; Linux has this flag, macosx doesn't, don't - # know about the other OSes - - # 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 - # OR'ing of flags: - const POSIX_SPAWN_USEVFORK* = cint(0) - when hasAioH: proc aio_cancel*(a1: cint, a2: ptr Taiocb): cint {.importc, header: "<aio.h>".} proc aio_error*(a1: ptr Taiocb): cint {.importc, header: "<aio.h>".} @@ -1913,11 +161,12 @@ proc fnmatch*(a1, a2: cstring, a3: cint): cint {.importc, header: "<fnmatch.h>". proc ftw*(a1: cstring, a2: proc (x1: cstring, x2: ptr Stat, x3: cint): cint {.noconv.}, a3: cint): cint {.importc, header: "<ftw.h>".} -proc nftw*(a1: cstring, - a2: proc (x1: cstring, x2: ptr Stat, - x3: cint, x4: ptr FTW): cint {.noconv.}, - a3: cint, - a4: cint): cint {.importc, header: "<ftw.h>".} +when not (defined(linux) and defined(amd64)): + proc nftw*(a1: cstring, + a2: proc (x1: cstring, x2: ptr Stat, + x3: cint, x4: ptr FTW): cint {.noconv.}, + a3: cint, + a4: cint): cint {.importc, header: "<ftw.h>".} proc glob*(a1: cstring, a2: cint, a3: proc (x1: cstring, x2: cint): cint {.noconv.}, @@ -2330,8 +579,9 @@ 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>".} -proc posix_typed_mem_get_info*(a1: cint, - a2: var Posix_typed_mem_info): cint {.importc, header: "<sys/mman.h>".} +when not (defined(linux) and defined(amd64)): + 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 {. importc, header: "<sys/mman.h>".} proc shm_open*(a1: cstring, a2: cint, a3: Mode): cint {. diff --git a/lib/posix/posix_linux_amd64.nim b/lib/posix/posix_linux_amd64.nim new file mode 100644 index 000000000..70f7e710f --- /dev/null +++ b/lib/posix/posix_linux_amd64.nim @@ -0,0 +1,613 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2012 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +# Types here should conform to the glibc ABI on linux / x86_64 +# When adding a type, the order and size of fields must match + +# To be included from posix.nim! + +from times import Time + +const + hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays + hasAioH = defined(linux) + +# On Linux: +# timer_{create,delete,settime,gettime}, +# clock_{getcpuclockid, getres, gettime, nanosleep, settime} lives in librt +{.passL: "-lrt".} + +# Types + +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 + Timespec* {.importc: "struct timespec", + header: "<time.h>", final, pure.} = object ## struct timespec + tv_sec*: Time ## Seconds. + tv_nsec*: clong ## Nanoseconds. + + Dirent* {.importc: "struct dirent", + header: "<dirent.h>", final, pure.} = object ## dirent_t struct + d_ino*: Ino + d_off*: Off + d_reclen*: cushort + d_type*: int8 # cuchar really! + d_name*: array[256, cchar] + + Tflock* {.importc: "struct flock", final, pure, + header: "<fcntl.h>".} = object ## flock type + l_type*: cshort ## Type of lock; F_RDLCK, F_WRLCK, F_UNLCK. + l_whence*: cshort ## Flag for starting offset. + l_start*: Off ## Relative offset in bytes. + l_len*: Off ## Size; if 0 then until EOF. + l_pid*: Pid ## Process ID of the process holding the lock; + ## returned with F_GETLK. + + # no struct FTW on linux + + Glob* {.importc: "glob_t", header: "<glob.h>", + final, pure.} = object ## glob_t + gl_pathc*: csize ## Count of paths matched by pattern. + gl_pathv*: cstringArray ## Pointer to a list of matched pathnames. + gl_offs*: csize ## Slots to reserve at the beginning of gl_pathv. + gl_flags*: cint + gl_closedir*: pointer + gl_readdir*: pointer + gl_opendir*: pointer + gl_lstat*: pointer + gl_stat*: pointer + + Group* {.importc: "struct group", header: "<grp.h>", + final, pure.} = object ## struct group + gr_name*: cstring ## The name of the group. + gr_passwd*: cstring + gr_gid*: Gid ## Numerical group ID. + gr_mem*: cstringArray ## Pointer to a null-terminated array of character + ## pointers to member names. + + Iconv* {.importc: "iconv_t", header: "<iconv.h>".} = pointer + ## Identifies the conversion from one codeset to another. + + Lconv* {.importc: "struct lconv", header: "<locale.h>", final, + pure.} = object + decimal_point*: cstring + thousands_sep*: cstring + grouping*: cstring + int_curr_symbol*: cstring + currency_symbol*: cstring + mon_decimal_point*: cstring + mon_thousands_sep*: cstring + mon_grouping*: cstring + positive_sign*: cstring + negative_sign*: cstring + int_frac_digits*: char + frac_digits*: char + p_cs_precedes*: char + p_sep_by_space*: char + n_cs_precedes*: char + n_sep_by_space*: char + p_sign_posn*: char + n_sign_posn*: char + int_p_cs_precedes*: char + int_p_sep_by_space*: char + int_n_cs_precedes*: char + int_n_sep_by_space*: char + int_p_sign_posn*: char + int_n_sign_posn*: char + + Mqd* {.importc: "mqd_t", header: "<mqueue.h>".} = cint + MqAttr* {.importc: "struct mq_attr", + header: "<mqueue.h>", + final, pure.} = object ## message queue attribute + mq_flags*: clong ## Message queue flags. + mq_maxmsg*: clong ## Maximum number of messages. + mq_msgsize*: clong ## Maximum message size. + mq_curmsgs*: clong ## Number of messages currently queued. + pad: array[4, clong] + + Passwd* {.importc: "struct passwd", header: "<pwd.h>", + final, pure.} = object ## struct passwd + pw_name*: cstring ## User's login name. + pw_passwd*: cstring + pw_uid*: Uid ## Numerical user ID. + pw_gid*: Gid ## Numerical group ID. + pw_gecos*: cstring + pw_dir*: cstring ## Initial working directory. + pw_shell*: cstring ## Program to use as shell. + + Blkcnt* {.importc: "blkcnt_t", header: "<sys/types.h>".} = clong + ## used for file block counts + Blksize* {.importc: "blksize_t", header: "<sys/types.h>".} = clong + ## used for block sizes + Clock* {.importc: "clock_t", header: "<sys/types.h>".} = clong + ClockId* {.importc: "clockid_t", header: "<sys/types.h>".} = cint + Dev* {.importc: "dev_t", header: "<sys/types.h>".} = culong + Fsblkcnt* {.importc: "fsblkcnt_t", header: "<sys/types.h>".} = culong + Fsfilcnt* {.importc: "fsfilcnt_t", header: "<sys/types.h>".} = culong + Gid* {.importc: "gid_t", header: "<sys/types.h>".} = cuint + Id* {.importc: "id_t", header: "<sys/types.h>".} = cuint + Ino* {.importc: "ino_t", header: "<sys/types.h>".} = culong + Key* {.importc: "key_t", header: "<sys/types.h>".} = cint + Mode* {.importc: "mode_t", header: "<sys/types.h>".} = cint # cuint really! + Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = culong + Off* {.importc: "off_t", header: "<sys/types.h>".} = clong + Pid* {.importc: "pid_t", header: "<sys/types.h>".} = cint + Pthread_attr* {.importc: "pthread_attr_t", header: "<sys/types.h>", + pure, final.} = object + abi: array[56 div sizeof(clong), clong] + + Pthread_barrier* {.importc: "pthread_barrier_t", + header: "<sys/types.h>", pure, final.} = object + abi: array[32 div sizeof(clong), clong] + Pthread_barrierattr* {.importc: "pthread_barrierattr_t", + header: "<sys/types.h>", pure, final.} = object + abi: array[4 div sizeof(cint), cint] + + Pthread_cond* {.importc: "pthread_cond_t", header: "<sys/types.h>", + pure, final.} = object + abi: array[48 div sizeof(clonglong), clonglong] + Pthread_condattr* {.importc: "pthread_condattr_t", + header: "<sys/types.h>", pure, final.} = object + abi: array[4 div sizeof(cint), cint] + Pthread_key* {.importc: "pthread_key_t", header: "<sys/types.h>".} = cuint + Pthread_mutex* {.importc: "pthread_mutex_t", header: "<sys/types.h>", + pure, final.} = object + abi: array[48 div sizeof(clong), clong] + Pthread_mutexattr* {.importc: "pthread_mutexattr_t", + header: "<sys/types.h>", pure, final.} = object + abi: array[4 div sizeof(cint), cint] + Pthread_once* {.importc: "pthread_once_t", header: "<sys/types.h>".} = cint + Pthread_rwlock* {.importc: "pthread_rwlock_t", + header: "<sys/types.h>", pure, final.} = object + abi: array[56 div sizeof(clong), clong] + Pthread_rwlockattr* {.importc: "pthread_rwlockattr_t", + header: "<sys/types.h>".} = object + abi: array[8 div sizeof(clong), clong] + Pthread_spinlock* {.importc: "pthread_spinlock_t", + header: "<sys/types.h>".} = cint + Pthread* {.importc: "pthread_t", header: "<sys/types.h>".} = culong + Suseconds* {.importc: "suseconds_t", header: "<sys/types.h>".} = clong + #Ttime* {.importc: "time_t", header: "<sys/types.h>".} = int + Timer* {.importc: "timer_t", header: "<sys/types.h>".} = pointer + Uid* {.importc: "uid_t", header: "<sys/types.h>".} = cuint + Useconds* {.importc: "useconds_t", header: "<sys/types.h>".} = cuint + + Utsname* {.importc: "struct utsname", + header: "<sys/utsname.h>", + final, pure.} = object ## struct utsname + sysname*, ## Name of this implementation of the operating system. + nodename*, ## Name of this node within the communications + ## network to which this node is attached, if any. + release*, ## Current release level of this implementation. + version*, ## Current version level of this release. + machine*, ## Name of the hardware type on which the + ## system is running. + domainname*: array[65, char] + + Sem* {.importc: "sem_t", header: "<semaphore.h>", final, pure.} = object + abi: array[32 div sizeof(clong), clong] + + Ipc_perm* {.importc: "struct ipc_perm", + header: "<sys/ipc.h>", final, pure.} = object ## struct ipc_perm + key: Key + uid*: Uid ## Owner's user ID. + gid*: Gid ## Owner's group ID. + cuid*: Uid ## Creator's user ID. + cgid*: Gid ## Creator's group ID. + mode*: cshort ## Read/write permission. + pad1: cshort + seq1: cshort + pad2: cshort + reserved1: culong + reserved2: culong + + Stat* {.importc: "struct stat", + header: "<sys/stat.h>", final, pure.} = object ## struct stat + st_dev*: Dev ## Device ID of device containing file. + st_ino*: Ino ## File serial number. + st_nlink*: Nlink ## Number of hard links to the file. + st_mode*: Mode ## Mode of file (see below). + st_uid*: Uid ## User ID of file. + st_gid*: Gid ## Group ID of file. + pad0: cint + st_rdev*: Dev ## Device ID (if file is character or block special). + st_size*: Off ## For regular files, the file size in bytes. + ## For symbolic links, the length in bytes of the + ## pathname contained in the symbolic link. + ## For a shared memory object, the length in bytes. + ## For a typed memory object, the length in bytes. + ## For other file types, the use of this field is + ## unspecified. + st_blksize*: Blksize ## A file system-specific preferred I/O block size + ## for this object. In some file system types, this + ## may vary from file to file. + st_blocks*: Blkcnt ## Number of blocks allocated for this object. + st_atim*: Timespec ## Time of last access. + st_mtim*: Timespec ## Time of last data modification. + st_ctim*: Timespec ## Time of last status change. + reserved: array[3, clong] + + + Statvfs* {.importc: "struct statvfs", header: "<sys/statvfs.h>", + final, pure.} = object ## struct statvfs + f_bsize*: culong ## File system block size. + f_frsize*: culong ## Fundamental file system block size. + f_blocks*: Fsblkcnt ## Total number of blocks on file system + ## in units of f_frsize. + f_bfree*: Fsblkcnt ## Total number of free blocks. + f_bavail*: Fsblkcnt ## Number of free blocks available to + ## non-privileged process. + f_files*: Fsfilcnt ## Total number of file serial numbers. + f_ffree*: Fsfilcnt ## Total number of free file serial numbers. + f_favail*: Fsfilcnt ## Number of file serial numbers available to + ## non-privileged process. + f_fsid*: culong ## File system ID. + f_flag*: culong ## Bit mask of f_flag values. + f_namemax*: culong ## Maximum filename length. + f_spare: array[6, cint] + + # No Posix_typed_mem_info + + Tm* {.importc: "struct tm", header: "<time.h>", + final, pure.} = object ## struct tm + tm_sec*: cint ## Seconds [0,60]. + tm_min*: cint ## Minutes [0,59]. + tm_hour*: cint ## Hour [0,23]. + tm_mday*: cint ## Day of month [1,31]. + tm_mon*: cint ## Month of year [0,11]. + tm_year*: cint ## Years since 1900. + tm_wday*: cint ## Day of week [0,6] (Sunday =0). + tm_yday*: cint ## Day of year [0,365]. + tm_isdst*: cint ## Daylight Savings flag. + tm_gmtoff*: clong + tm_zone*: cstring + + Itimerspec* {.importc: "struct itimerspec", header: "<time.h>", + final, pure.} = object ## struct itimerspec + it_interval*: Timespec ## Timer period. + it_value*: Timespec ## Timer expiration. + + Sig_atomic* {.importc: "sig_atomic_t", header: "<signal.h>".} = cint + ## Possibly volatile-qualified integer type of an object that can be + ## accessed as an atomic entity, even in the presence of asynchronous + ## interrupts. + Sigset* {.importc: "sigset_t", header: "<signal.h>", final, pure.} = object + abi: array[1024 div (8 * sizeof(culong)), culong] + + SigEvent* {.importc: "struct sigevent", + header: "<signal.h>", final, pure.} = object ## struct sigevent + sigev_value*: SigVal ## Signal value. + sigev_signo*: cint ## Signal number. + sigev_notify*: cint ## Notification type. + sigev_notify_function*: proc (x: SigVal) {.noconv.} ## Notification func. + sigev_notify_attributes*: ptr PthreadAttr ## Notification attributes. + abi: array[12, int] + + SigVal* {.importc: "union sigval", + header: "<signal.h>", final, pure.} = object ## struct sigval + sival_ptr*: pointer ## pointer signal value; + ## integer signal value not defined! + Sigaction* {.importc: "struct sigaction", + header: "<signal.h>", final, pure.} = object ## struct sigaction + sa_handler*: proc (x: cint) {.noconv.} ## Pointer to a signal-catching + ## function or one of the macros + ## SIG_IGN or SIG_DFL. + sa_mask*: Sigset ## Set of signals to be blocked during execution of + ## the signal handling function. + sa_flags*: cint ## Special flags. + sa_sigaction*: proc (x: cint, y: ptr SigInfo, z: pointer) {.noconv.} + + Stack* {.importc: "stack_t", + header: "<signal.h>", final, pure.} = object ## stack_t + ss_sp*: pointer ## Stack base or pointer. + ss_size*: int ## Stack size. + ss_flags*: cint ## Flags. + + SigStack* {.importc: "struct sigstack", + header: "<signal.h>", final, pure.} = object ## struct sigstack + ss_onstack*: cint ## Non-zero when signal stack is in use. + ss_sp*: pointer ## Signal stack pointer. + + SigInfo* {.importc: "siginfo_t", + header: "<signal.h>", final, pure.} = object ## siginfo_t + si_signo*: cint ## Signal number. + si_code*: cint ## Signal code. + si_errno*: cint ## If non-zero, an errno value associated with + ## this signal, as defined in <errno.h>. + si_pid*: Pid ## Sending process ID. + si_uid*: Uid ## Real user ID of sending process. + si_addr*: pointer ## Address of faulting instruction. + si_status*: cint ## Exit value or signal. + si_band*: int ## Band event for SIGPOLL. + si_value*: SigVal ## Signal value. + pad {.importc: "_pad"}: array[128 - 56, uint8] + + Nl_item* {.importc: "nl_item", header: "<nl_types.h>".} = cint + Nl_catd* {.importc: "nl_catd", header: "<nl_types.h>".} = pointer + + Sched_param* {.importc: "struct sched_param", + header: "<sched.h>", + final, pure.} = object ## struct sched_param + sched_priority*: cint + + Timeval* {.importc: "struct timeval", header: "<sys/select.h>", + final, pure.} = object ## struct timeval + tv_sec*: clong ## Seconds. + tv_usec*: clong ## Microseconds. + TFdSet* {.importc: "fd_set", header: "<sys/select.h>", + final, pure.} = object + abi: array[1024 div (8 * sizeof(clong)), clong] + + Mcontext* {.importc: "mcontext_t", header: "<ucontext.h>", + final, pure.} = object + gregs: array[23, clonglong] + fpregs: pointer + reserved1: array[8, clonglong] + + Ucontext* {.importc: "ucontext_t", header: "<ucontext.h>", + final, pure.} = object ## ucontext_t + uc_flags: clong + uc_link*: ptr Ucontext ## Pointer to the context that is resumed + ## when this context returns. + uc_stack*: Stack ## The stack used by this context. + uc_mcontext*: Mcontext ## A machine-specific representation of the saved + ## context. + uc_sigmask*: Sigset ## The set of signals that are blocked when this + ## context is active. + # todo fpregds_mem + +{.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, 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, + Tuid: Uid, Tuseconds: Useconds, Tutsname: Utsname, Tipc_perm: Ipc_perm, + TStat: Stat, TStatvfs: Statvfs, + 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].} +type + Taiocb* {.importc: "struct aiocb", header: "<aio.h>", + final, pure.} = object ## struct aiocb + aio_fildes*: cint ## File descriptor. + aio_lio_opcode*: cint ## Operation to be performed. + aio_reqprio*: cint ## Request priority offset. + aio_buf*: pointer ## Location of buffer. + aio_nbytes*: csize ## Length of transfer. + aio_sigevent*: SigEvent ## Signal number and value. + next_prio: pointer + abs_prio: cint + policy: cint + error_Code: cint + return_value: clong + aio_offset*: Off ## File offset. + reserved: array[32, uint8] + + +when hasSpawnH: + type + Tposix_spawnattr* {.importc: "posix_spawnattr_t", + header: "<spawn.h>", final, pure.} = object + flags: cshort + pgrp: Pid + sd: Sigset + ss: Sigset + sp: Sched_param + policy: cint + pad: array[16, cint] + + Tposix_spawn_file_actions* {.importc: "posix_spawn_file_actions_t", + header: "<spawn.h>", final, pure.} = object + allocated: cint + used: cint + actions: pointer + pad: array[16, cint] + +# from sys/un.h +const Sockaddr_un_path_length* = 108 + +type + Socklen* {.importc: "socklen_t", header: "<sys/socket.h>".} = cuint + # cushort really + TSa_Family* {.importc: "sa_family_t", header: "<sys/socket.h>".} = cshort + + SockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>", + pure, final.} = object ## struct sockaddr + sa_family*: TSa_Family ## Address family. + sa_data*: array[14, char] ## Socket address (variable-length data). + + 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[108, 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. + ss_padding: array[128 - sizeof(cshort) - sizeof(culong), char] + ss_align: clong + + Tif_nameindex* {.importc: "struct if_nameindex", final, + pure, header: "<net/if.h>".} = object ## struct if_nameindex + if_index*: cuint ## Numeric index of the interface. + if_name*: cstring ## Null-terminated name of the interface. + + + 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*: csize ## 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_iov*: ptr IOVec ## Scatter/gather array. + msg_iovlen*: csize ## Members in msg_iov. + msg_control*: pointer ## Ancillary data; see below. + msg_controllen*: csize ## 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*: csize ## Data byte count, including the cmsghdr. + cmsg_level*: cint ## Originating protocol. + cmsg_type*: cint ## Protocol-specific type. + + TLinger* {.importc: "struct linger", pure, final, + header: "<sys/socket.h>".} = object ## struct linger + l_onoff*: cint ## Indicates whether linger option is enabled. + l_linger*: cint ## Linger time, in seconds. + # data follows... + + InPort* = uint16 + InAddrScalar* = uint32 + + InAddrT* {.importc: "in_addr_t", pure, final, + header: "<netinet/in.h>".} = uint32 + + InAddr* {.importc: "struct in_addr", pure, final, + header: "<netinet/in.h>".} = object ## struct in_addr + s_addr*: InAddrScalar + + Sockaddr_in* {.importc: "struct sockaddr_in", pure, final, + header: "<netinet/in.h>".} = object ## struct sockaddr_in + sin_family*: TSa_Family ## AF_INET. + sin_port*: InPort ## Port number. + sin_addr*: InAddr ## IP address. + sin_zero: array[16 - 2 - 2 - 4, uint8] + + In6Addr* {.importc: "struct in6_addr", pure, final, + header: "<netinet/in.h>".} = object ## struct in6_addr + s6_addr*: array[0..15, char] + + Sockaddr_in6* {.importc: "struct sockaddr_in6", pure, final, + header: "<netinet/in.h>".} = object ## struct sockaddr_in6 + sin6_family*: TSa_Family ## AF_INET6. + sin6_port*: InPort ## Port number. + sin6_flowinfo*: uint32 ## IPv6 traffic class and flow information. + sin6_addr*: In6Addr ## IPv6 address. + sin6_scope_id*: uint32 ## Set of interfaces for a scope. + + Tipv6_mreq* {.importc: "struct ipv6_mreq", pure, final, + header: "<netinet/in.h>".} = object ## struct ipv6_mreq + ipv6mr_multiaddr*: In6Addr ## IPv6 multicast address. + ipv6mr_interface*: cuint ## Interface index. + + Hostent* {.importc: "struct hostent", pure, final, + header: "<netdb.h>".} = object ## struct hostent + h_name*: cstring ## Official name of the host. + h_aliases*: cstringArray ## A pointer to an array of pointers to + ## alternative host names, terminated by a + ## null pointer. + h_addrtype*: cint ## Address type. + h_length*: cint ## The length, in bytes, of the address. + h_addr_list*: cstringArray ## A pointer to an array of pointers to network + ## addresses (in network byte order) for the + ## host, terminated by a null pointer. + + Tnetent* {.importc: "struct netent", pure, final, + header: "<netdb.h>".} = object ## struct netent + n_name*: cstring ## Official, fully-qualified (including the + ## domain) name of the host. + n_aliases*: cstringArray ## A pointer to an array of pointers to + ## alternative network names, terminated by a + ## null pointer. + n_addrtype*: cint ## The address type of the network. + n_net*: uint32 ## The network number, in host byte order. + + Protoent* {.importc: "struct protoent", pure, final, + header: "<netdb.h>".} = object ## struct protoent + p_name*: cstring ## Official name of the protocol. + p_aliases*: cstringArray ## A pointer to an array of pointers to + ## alternative protocol names, terminated by + ## a null pointer. + p_proto*: cint ## The protocol number. + + Servent* {.importc: "struct servent", pure, final, + header: "<netdb.h>".} = object ## struct servent + s_name*: cstring ## Official name of the service. + s_aliases*: cstringArray ## A pointer to an array of pointers to + ## alternative service names, terminated by + ## a null pointer. + s_port*: cint ## The port number at which the service + ## resides, in network byte order. + s_proto*: cstring ## The name of the protocol to use when + ## contacting the service. + + AddrInfo* {.importc: "struct addrinfo", pure, final, + header: "<netdb.h>".} = object ## struct addrinfo + ai_flags*: cint ## Input flags. + 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_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>".} = culong + +{.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].} + +var + errno* {.importc, header: "<errno.h>".}: cint ## error variable + h_errno* {.importc, header: "<netdb.h>".}: cint + daylight* {.importc, header: "<time.h>".}: cint + timezone* {.importc, header: "<time.h>".}: clong + +# Regenerate using detect.nim! +include posix_linux_amd64_consts + +const POSIX_SPAWN_USEVFORK* = cint(0x40) # needs _GNU_SOURCE! + +# <sys/wait.h> +proc WEXITSTATUS*(s: cint): cint = (s and 0xff00) shr 8 +proc WTERMSIG*(s:cint): cint = s and 0x7f +proc WSTOPSIG*(s:cint): cint = WEXITSTATUS(s) +proc WIFEXITED*(s:cint) : bool = WTERMSIG(s) == 0 +proc WIFSIGNALED*(s:cint) : bool = (cast[int8]((s and 0x7f) + 1) shr 1) > 0 +proc WIFSTOPPED*(s:cint) : bool = (s and 0xff) == 0x7f +proc WIFCONTINUED*(s:cint) : bool = s == W_CONTINUED diff --git a/lib/posix/posix_linux_amd64_consts.nim b/lib/posix/posix_linux_amd64_consts.nim new file mode 100644 index 000000000..9e2ed32e1 --- /dev/null +++ b/lib/posix/posix_linux_amd64_consts.nim @@ -0,0 +1,702 @@ +# Generated by detect.nim + + +# <aio.h> +const AIO_ALLDONE* = cint(2) +const AIO_CANCELED* = cint(0) +const AIO_NOTCANCELED* = cint(1) +const LIO_NOP* = cint(2) +const LIO_NOWAIT* = cint(1) +const LIO_READ* = cint(0) +const LIO_WAIT* = cint(0) +const LIO_WRITE* = cint(1) + +# <dlfcn.h> +const RTLD_LAZY* = cint(1) +const RTLD_NOW* = cint(2) +const RTLD_GLOBAL* = cint(256) +const RTLD_LOCAL* = cint(0) + +# <errno.h> +const E2BIG* = cint(7) +const EACCES* = cint(13) +const EADDRINUSE* = cint(98) +const EADDRNOTAVAIL* = cint(99) +const EAFNOSUPPORT* = cint(97) +const EAGAIN* = cint(11) +const EALREADY* = cint(114) +const EBADF* = cint(9) +const EBADMSG* = cint(74) +const EBUSY* = cint(16) +const ECANCELED* = cint(125) +const ECHILD* = cint(10) +const ECONNABORTED* = cint(103) +const ECONNREFUSED* = cint(111) +const ECONNRESET* = cint(104) +const EDEADLK* = cint(35) +const EDESTADDRREQ* = cint(89) +const EDOM* = cint(33) +const EDQUOT* = cint(122) +const EEXIST* = cint(17) +const EFAULT* = cint(14) +const EFBIG* = cint(27) +const EHOSTUNREACH* = cint(113) +const EIDRM* = cint(43) +const EILSEQ* = cint(84) +const EINPROGRESS* = cint(115) +const EINTR* = cint(4) +const EINVAL* = cint(22) +const EIO* = cint(5) +const EISCONN* = cint(106) +const EISDIR* = cint(21) +const ELOOP* = cint(40) +const EMFILE* = cint(24) +const EMLINK* = cint(31) +const EMSGSIZE* = cint(90) +const EMULTIHOP* = cint(72) +const ENAMETOOLONG* = cint(36) +const ENETDOWN* = cint(100) +const ENETRESET* = cint(102) +const ENETUNREACH* = cint(101) +const ENFILE* = cint(23) +const ENOBUFS* = cint(105) +const ENODATA* = cint(61) +const ENODEV* = cint(19) +const ENOENT* = cint(2) +const ENOEXEC* = cint(8) +const ENOLCK* = cint(37) +const ENOLINK* = cint(67) +const ENOMEM* = cint(12) +const ENOMSG* = cint(42) +const ENOPROTOOPT* = cint(92) +const ENOSPC* = cint(28) +const ENOSR* = cint(63) +const ENOSTR* = cint(60) +const ENOSYS* = cint(38) +const ENOTCONN* = cint(107) +const ENOTDIR* = cint(20) +const ENOTEMPTY* = cint(39) +const ENOTSOCK* = cint(88) +const ENOTSUP* = cint(95) +const ENOTTY* = cint(25) +const ENXIO* = cint(6) +const EOPNOTSUPP* = cint(95) +const EOVERFLOW* = cint(75) +const EPERM* = cint(1) +const EPIPE* = cint(32) +const EPROTO* = cint(71) +const EPROTONOSUPPORT* = cint(93) +const EPROTOTYPE* = cint(91) +const ERANGE* = cint(34) +const EROFS* = cint(30) +const ESPIPE* = cint(29) +const ESRCH* = cint(3) +const ESTALE* = cint(116) +const ETIME* = cint(62) +const ETIMEDOUT* = cint(110) +const ETXTBSY* = cint(26) +const EWOULDBLOCK* = cint(11) +const EXDEV* = cint(18) + +# <fcntl.h> +const F_DUPFD* = cint(0) +const F_GETFD* = cint(1) +const F_SETFD* = cint(2) +const F_GETFL* = cint(3) +const F_SETFL* = cint(4) +const F_GETLK* = cint(5) +const F_SETLK* = cint(6) +const F_SETLKW* = cint(7) +const F_GETOWN* = cint(9) +const F_SETOWN* = cint(8) +const FD_CLOEXEC* = cint(1) +const F_RDLCK* = cint(0) +const F_UNLCK* = cint(2) +const F_WRLCK* = cint(1) +const O_CREAT* = cint(64) +const O_EXCL* = cint(128) +const O_NOCTTY* = cint(256) +const O_TRUNC* = cint(512) +const O_APPEND* = cint(1024) +const O_DSYNC* = cint(4096) +const O_NONBLOCK* = cint(2048) +const O_RSYNC* = cint(1052672) +const O_SYNC* = cint(1052672) +const O_ACCMODE* = cint(3) +const O_RDONLY* = cint(0) +const O_RDWR* = cint(2) +const O_WRONLY* = cint(1) +const POSIX_FADV_NORMAL* = cint(0) +const POSIX_FADV_SEQUENTIAL* = cint(2) +const POSIX_FADV_RANDOM* = cint(1) +const POSIX_FADV_WILLNEED* = cint(3) +const POSIX_FADV_DONTNEED* = cint(4) +const POSIX_FADV_NOREUSE* = cint(5) + +# <fenv.h> +const FE_DIVBYZERO* = cint(4) +const FE_INEXACT* = cint(32) +const FE_INVALID* = cint(1) +const FE_OVERFLOW* = cint(8) +const FE_UNDERFLOW* = cint(16) +const FE_ALL_EXCEPT* = cint(61) +const FE_DOWNWARD* = cint(1024) +const FE_TONEAREST* = cint(0) +const FE_TOWARDZERO* = cint(3072) +const FE_UPWARD* = cint(2048) +const FE_DFL_ENV* = cint(-1) + +# <fmtmsg.h> +const MM_HARD* = cint(1) +const MM_SOFT* = cint(2) +const MM_FIRM* = cint(4) +const MM_APPL* = cint(8) +const MM_UTIL* = cint(16) +const MM_OPSYS* = cint(32) +const MM_RECOVER* = cint(64) +const MM_NRECOV* = cint(128) +const MM_HALT* = cint(1) +const MM_ERROR* = cint(2) +const MM_WARNING* = cint(3) +const MM_INFO* = cint(4) +const MM_NOSEV* = cint(0) +const MM_PRINT* = cint(256) +const MM_CONSOLE* = cint(512) +const MM_OK* = cint(0) +const MM_NOTOK* = cint(-1) +const MM_NOMSG* = cint(1) +const MM_NOCON* = cint(4) + +# <fnmatch.h> +const FNM_NOMATCH* = cint(1) +const FNM_PATHNAME* = cint(1) +const FNM_PERIOD* = cint(4) +const FNM_NOESCAPE* = cint(2) + +# <ftw.h> +const FTW_F* = cint(0) +const FTW_D* = cint(1) +const FTW_DNR* = cint(2) +const FTW_NS* = cint(3) +const FTW_SL* = cint(4) + +# <glob.h> +const GLOB_APPEND* = cint(32) +const GLOB_DOOFFS* = cint(8) +const GLOB_ERR* = cint(1) +const GLOB_MARK* = cint(2) +const GLOB_NOCHECK* = cint(16) +const GLOB_NOESCAPE* = cint(64) +const GLOB_NOSORT* = cint(4) +const GLOB_ABORTED* = cint(2) +const GLOB_NOMATCH* = cint(3) +const GLOB_NOSPACE* = cint(1) +const GLOB_NOSYS* = cint(4) + +# <langinfo.h> +const CODESET* = cint(14) +const D_T_FMT* = cint(131112) +const D_FMT* = cint(131113) +const T_FMT* = cint(131114) +const T_FMT_AMPM* = cint(131115) +const AM_STR* = cint(131110) +const PM_STR* = cint(131111) +const DAY_1* = cint(131079) +const DAY_2* = cint(131080) +const DAY_3* = cint(131081) +const DAY_4* = cint(131082) +const DAY_5* = cint(131083) +const DAY_6* = cint(131084) +const DAY_7* = cint(131085) +const ABDAY_1* = cint(131072) +const ABDAY_2* = cint(131073) +const ABDAY_3* = cint(131074) +const ABDAY_4* = cint(131075) +const ABDAY_5* = cint(131076) +const ABDAY_6* = cint(131077) +const ABDAY_7* = cint(131078) +const MON_1* = cint(131098) +const MON_2* = cint(131099) +const MON_3* = cint(131100) +const MON_4* = cint(131101) +const MON_5* = cint(131102) +const MON_6* = cint(131103) +const MON_7* = cint(131104) +const MON_8* = cint(131105) +const MON_9* = cint(131106) +const MON_10* = cint(131107) +const MON_11* = cint(131108) +const MON_12* = cint(131109) +const ABMON_1* = cint(131086) +const ABMON_2* = cint(131087) +const ABMON_3* = cint(131088) +const ABMON_4* = cint(131089) +const ABMON_5* = cint(131090) +const ABMON_6* = cint(131091) +const ABMON_7* = cint(131092) +const ABMON_8* = cint(131093) +const ABMON_9* = cint(131094) +const ABMON_10* = cint(131095) +const ABMON_11* = cint(131096) +const ABMON_12* = cint(131097) +const ERA* = cint(131116) +const ERA_D_FMT* = cint(131118) +const ERA_D_T_FMT* = cint(131120) +const ERA_T_FMT* = cint(131121) +const ALT_DIGITS* = cint(131119) +const RADIXCHAR* = cint(65536) +const THOUSEP* = cint(65537) +const YESEXPR* = cint(327680) +const NOEXPR* = cint(327681) +const CRNCYSTR* = cint(262159) + +# <locale.h> +const LC_ALL* = cint(6) +const LC_COLLATE* = cint(3) +const LC_CTYPE* = cint(0) +const LC_MESSAGES* = cint(5) +const LC_MONETARY* = cint(4) +const LC_NUMERIC* = cint(1) +const LC_TIME* = cint(2) + +# <netdb.h> +const IPPORT_RESERVED* = cint(1024) +const HOST_NOT_FOUND* = cint(1) +const NO_DATA* = cint(4) +const NO_RECOVERY* = cint(3) +const TRY_AGAIN* = cint(2) +const AI_PASSIVE* = cint(1) +const AI_CANONNAME* = cint(2) +const AI_NUMERICHOST* = cint(4) +const AI_NUMERICSERV* = cint(1024) +const AI_V4MAPPED* = cint(8) +const AI_ALL* = cint(16) +const AI_ADDRCONFIG* = cint(32) +const NI_NOFQDN* = cint(4) +const NI_NUMERICHOST* = cint(1) +const NI_NAMEREQD* = cint(8) +const NI_NUMERICSERV* = cint(2) +const NI_DGRAM* = cint(16) +const EAI_AGAIN* = cint(-3) +const EAI_BADFLAGS* = cint(-1) +const EAI_FAIL* = cint(-4) +const EAI_FAMILY* = cint(-6) +const EAI_MEMORY* = cint(-10) +const EAI_NONAME* = cint(-2) +const EAI_SERVICE* = cint(-8) +const EAI_SOCKTYPE* = cint(-7) +const EAI_SYSTEM* = cint(-11) +const EAI_OVERFLOW* = cint(-12) + +# <net/if.h> +const IF_NAMESIZE* = cint(16) + +# <netinet/in.h> +const IPPROTO_IP* = cint(0) +const IPPROTO_IPV6* = cint(41) +const IPPROTO_ICMP* = cint(1) +const IPPROTO_RAW* = cint(255) +const IPPROTO_TCP* = cint(6) +const IPPROTO_UDP* = cint(17) +const INADDR_ANY* = InAddrScalar(0) +const INADDR_LOOPBACK* = InAddrScalar(2130706433) +const INADDR_BROADCAST* = InAddrScalar(-1) +const INET_ADDRSTRLEN* = cint(16) +const INET6_ADDRSTRLEN* = cint(46) +const IPV6_JOIN_GROUP* = cint(20) +const IPV6_LEAVE_GROUP* = cint(21) +const IPV6_MULTICAST_HOPS* = cint(18) +const IPV6_MULTICAST_IF* = cint(17) +const IPV6_MULTICAST_LOOP* = cint(19) +const IPV6_UNICAST_HOPS* = cint(16) +const IPV6_V6ONLY* = cint(26) + +# <netinet/tcp.h> +const TCP_NODELAY* = cint(1) + +# <nl_types.h> +const NL_SETD* = cint(1) +const NL_CAT_LOCALE* = cint(1) + +# <poll.h> +const POLLIN* = cshort(1) +const POLLRDNORM* = cshort(64) +const POLLRDBAND* = cshort(128) +const POLLPRI* = cshort(2) +const POLLOUT* = cshort(4) +const POLLWRNORM* = cshort(256) +const POLLWRBAND* = cshort(512) +const POLLERR* = cshort(8) +const POLLHUP* = cshort(16) +const POLLNVAL* = cshort(32) + +# <pthread.h> +const PTHREAD_BARRIER_SERIAL_THREAD* = cint(-1) +const PTHREAD_CANCEL_ASYNCHRONOUS* = cint(1) +const PTHREAD_CANCEL_ENABLE* = cint(0) +const PTHREAD_CANCEL_DEFERRED* = cint(0) +const PTHREAD_CANCEL_DISABLE* = cint(1) +const PTHREAD_CREATE_DETACHED* = cint(1) +const PTHREAD_CREATE_JOINABLE* = cint(0) +const PTHREAD_EXPLICIT_SCHED* = cint(1) +const PTHREAD_INHERIT_SCHED* = cint(0) +const PTHREAD_PROCESS_SHARED* = cint(1) +const PTHREAD_PROCESS_PRIVATE* = cint(0) +const PTHREAD_SCOPE_PROCESS* = cint(1) +const PTHREAD_SCOPE_SYSTEM* = cint(0) + +# <sched.h> +const SCHED_FIFO* = cint(1) +const SCHED_RR* = cint(2) +const SCHED_OTHER* = cint(0) + +# <semaphore.h> +const SEM_FAILED* = cast[pointer]((nil)) + +# <signal.h> +const SIGEV_NONE* = cint(1) +const SIGEV_SIGNAL* = cint(0) +const SIGEV_THREAD* = cint(2) +const SIGABRT* = cint(6) +const SIGALRM* = cint(14) +const SIGBUS* = cint(7) +const SIGCHLD* = cint(17) +const SIGCONT* = cint(18) +const SIGFPE* = cint(8) +const SIGHUP* = cint(1) +const SIGILL* = cint(4) +const SIGINT* = cint(2) +const SIGKILL* = cint(9) +const SIGPIPE* = cint(13) +const SIGQUIT* = cint(3) +const SIGSEGV* = cint(11) +const SIGSTOP* = cint(19) +const SIGTERM* = cint(15) +const SIGTSTP* = cint(20) +const SIGTTIN* = cint(21) +const SIGTTOU* = cint(22) +const SIGUSR1* = cint(10) +const SIGUSR2* = cint(12) +const SIGPOLL* = cint(29) +const SIGPROF* = cint(27) +const SIGSYS* = cint(31) +const SIGTRAP* = cint(5) +const SIGURG* = cint(23) +const SIGVTALRM* = cint(26) +const SIGXCPU* = cint(24) +const SIGXFSZ* = cint(25) +const SA_NOCLDSTOP* = cint(1) +const SIG_BLOCK* = cint(0) +const SIG_UNBLOCK* = cint(1) +const SIG_SETMASK* = cint(2) +const SA_ONSTACK* = cint(134217728) +const SA_RESETHAND* = cint(-2147483648) +const SA_RESTART* = cint(268435456) +const SA_SIGINFO* = cint(4) +const SA_NOCLDWAIT* = cint(2) +const SA_NODEFER* = cint(1073741824) +const SS_ONSTACK* = cint(1) +const SS_DISABLE* = cint(2) +const MINSIGSTKSZ* = cint(2048) +const SIGSTKSZ* = cint(8192) + +# <sys/ipc.h> +const IPC_CREAT* = cint(512) +const IPC_EXCL* = cint(1024) +const IPC_NOWAIT* = cint(2048) +const IPC_PRIVATE* = cint(0) +const IPC_RMID* = cint(0) +const IPC_SET* = cint(1) +const IPC_STAT* = cint(2) + +# <sys/mman.h> +const PROT_READ* = cint(1) +const PROT_WRITE* = cint(2) +const PROT_EXEC* = cint(4) +const PROT_NONE* = cint(0) +const MAP_SHARED* = cint(1) +const MAP_PRIVATE* = cint(2) +const MAP_FIXED* = cint(16) +const MS_ASYNC* = cint(1) +const MS_SYNC* = cint(4) +const MS_INVALIDATE* = cint(2) +const MCL_CURRENT* = cint(1) +const MCL_FUTURE* = cint(2) +const MAP_FAILED* = cast[pointer](0xffffffffffffffff) +const POSIX_MADV_NORMAL* = cint(0) +const POSIX_MADV_SEQUENTIAL* = cint(2) +const POSIX_MADV_RANDOM* = cint(1) +const POSIX_MADV_WILLNEED* = cint(3) +const POSIX_MADV_DONTNEED* = cint(4) +const MAP_POPULATE* = cint(32768) + +# <sys/select.h> +const FD_SETSIZE* = cint(1024) + +# <sys/socket.h> +const MSG_CTRUNC* = cint(8) +const MSG_DONTROUTE* = cint(4) +const MSG_EOR* = cint(128) +const MSG_OOB* = cint(1) +const SCM_RIGHTS* = cint(1) +const SO_ACCEPTCONN* = cint(30) +const SO_BROADCAST* = cint(6) +const SO_DEBUG* = cint(1) +const SO_DONTROUTE* = cint(5) +const SO_ERROR* = cint(4) +const SO_KEEPALIVE* = cint(9) +const SO_LINGER* = cint(13) +const SO_OOBINLINE* = cint(10) +const SO_RCVBUF* = cint(8) +const SO_RCVLOWAT* = cint(18) +const SO_RCVTIMEO* = cint(20) +const SO_REUSEADDR* = cint(2) +const SO_SNDBUF* = cint(7) +const SO_SNDLOWAT* = cint(19) +const SO_SNDTIMEO* = cint(21) +const SO_TYPE* = cint(3) +const SOCK_DGRAM* = cint(2) +const SOCK_RAW* = cint(3) +const SOCK_SEQPACKET* = cint(5) +const SOCK_STREAM* = cint(1) +const SOL_SOCKET* = cint(1) +const SOMAXCONN* = cint(128) +const SO_REUSEPORT* = cint(15) +const MSG_NOSIGNAL* = cint(16384) +const MSG_PEEK* = cint(2) +const MSG_TRUNC* = cint(32) +const MSG_WAITALL* = cint(256) +const AF_INET* = TSa_Family(2) +const AF_INET6* = TSa_Family(10) +const AF_UNIX* = TSa_Family(1) +const AF_UNSPEC* = TSa_Family(0) +const SHUT_RD* = cint(0) +const SHUT_RDWR* = cint(2) +const SHUT_WR* = cint(1) + +# <sys/stat.h> +const S_IFBLK* = cint(24576) +const S_IFCHR* = cint(8192) +const S_IFDIR* = cint(16384) +const S_IFIFO* = cint(4096) +const S_IFLNK* = cint(40960) +const S_IFMT* = cint(61440) +const S_IFREG* = cint(32768) +const S_IFSOCK* = cint(49152) +const S_IRGRP* = cint(32) +const S_IROTH* = cint(4) +const S_IRUSR* = cint(256) +const S_IRWXG* = cint(56) +const S_IRWXO* = cint(7) +const S_IRWXU* = cint(448) +const S_ISGID* = cint(1024) +const S_ISUID* = cint(2048) +const S_ISVTX* = cint(512) +const S_IWGRP* = cint(16) +const S_IWOTH* = cint(2) +const S_IWUSR* = cint(128) +const S_IXGRP* = cint(8) +const S_IXOTH* = cint(1) +const S_IXUSR* = cint(64) + +# <sys/statvfs.h> +const ST_RDONLY* = cint(1) +const ST_NOSUID* = cint(2) + +# <sys/wait.h> +const WNOHANG* = cint(1) +const WUNTRACED* = cint(2) +const WEXITED* = cint(4) +const WSTOPPED* = cint(2) +const WCONTINUED* = cint(8) +const WNOWAIT* = cint(16777216) + +# <spawn.h> +const POSIX_SPAWN_RESETIDS* = cint(1) +const POSIX_SPAWN_SETPGROUP* = cint(2) +const POSIX_SPAWN_SETSCHEDPARAM* = cint(16) +const POSIX_SPAWN_SETSCHEDULER* = cint(32) +const POSIX_SPAWN_SETSIGDEF* = cint(4) +const POSIX_SPAWN_SETSIGMASK* = cint(8) + +# <stdio.h> +const IOFBF* = cint(0) +const IONBF* = cint(2) + +# <time.h> +const CLOCKS_PER_SEC* = clong(1000000) +const CLOCK_PROCESS_CPUTIME_ID* = cint(2) +const CLOCK_THREAD_CPUTIME_ID* = cint(3) +const CLOCK_REALTIME* = cint(0) +const TIMER_ABSTIME* = cint(1) +const CLOCK_MONOTONIC* = cint(1) + +# <unistd.h> +const POSIX_ASYNC_IO* = cint(1) +const F_OK* = cint(0) +const R_OK* = cint(4) +const W_OK* = cint(2) +const X_OK* = cint(1) +const CS_PATH* = cint(0) +const CS_POSIX_V6_ILP32_OFF32_CFLAGS* = cint(1116) +const CS_POSIX_V6_ILP32_OFF32_LDFLAGS* = cint(1117) +const CS_POSIX_V6_ILP32_OFF32_LIBS* = cint(1118) +const CS_POSIX_V6_ILP32_OFFBIG_CFLAGS* = cint(1120) +const CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS* = cint(1121) +const CS_POSIX_V6_ILP32_OFFBIG_LIBS* = cint(1122) +const CS_POSIX_V6_LP64_OFF64_CFLAGS* = cint(1124) +const CS_POSIX_V6_LP64_OFF64_LDFLAGS* = cint(1125) +const CS_POSIX_V6_LP64_OFF64_LIBS* = cint(1126) +const CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS* = cint(1128) +const CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS* = cint(1129) +const CS_POSIX_V6_LPBIG_OFFBIG_LIBS* = cint(1130) +const CS_POSIX_V6_WIDTH_RESTRICTED_ENVS* = cint(1) +const F_LOCK* = cint(1) +const F_TEST* = cint(3) +const F_TLOCK* = cint(2) +const F_ULOCK* = cint(0) +const PC_2_SYMLINKS* = cint(20) +const PC_ALLOC_SIZE_MIN* = cint(18) +const PC_ASYNC_IO* = cint(10) +const PC_CHOWN_RESTRICTED* = cint(6) +const PC_FILESIZEBITS* = cint(13) +const PC_LINK_MAX* = cint(0) +const PC_MAX_CANON* = cint(1) +const PC_MAX_INPUT* = cint(2) +const PC_NAME_MAX* = cint(3) +const PC_NO_TRUNC* = cint(7) +const PC_PATH_MAX* = cint(4) +const PC_PIPE_BUF* = cint(5) +const PC_PRIO_IO* = cint(11) +const PC_REC_INCR_XFER_SIZE* = cint(14) +const PC_REC_MIN_XFER_SIZE* = cint(16) +const PC_REC_XFER_ALIGN* = cint(17) +const PC_SYMLINK_MAX* = cint(19) +const PC_SYNC_IO* = cint(9) +const PC_VDISABLE* = cint(8) +const SC_2_C_BIND* = cint(47) +const SC_2_C_DEV* = cint(48) +const SC_2_CHAR_TERM* = cint(95) +const SC_2_FORT_DEV* = cint(49) +const SC_2_FORT_RUN* = cint(50) +const SC_2_LOCALEDEF* = cint(52) +const SC_2_PBS* = cint(168) +const SC_2_PBS_ACCOUNTING* = cint(169) +const SC_2_PBS_CHECKPOINT* = cint(175) +const SC_2_PBS_LOCATE* = cint(170) +const SC_2_PBS_MESSAGE* = cint(171) +const SC_2_PBS_TRACK* = cint(172) +const SC_2_SW_DEV* = cint(51) +const SC_2_UPE* = cint(97) +const SC_2_VERSION* = cint(46) +const SC_ADVISORY_INFO* = cint(132) +const SC_AIO_LISTIO_MAX* = cint(23) +const SC_AIO_MAX* = cint(24) +const SC_AIO_PRIO_DELTA_MAX* = cint(25) +const SC_ARG_MAX* = cint(0) +const SC_ASYNCHRONOUS_IO* = cint(12) +const SC_ATEXIT_MAX* = cint(87) +const SC_BARRIERS* = cint(133) +const SC_BC_BASE_MAX* = cint(36) +const SC_BC_DIM_MAX* = cint(37) +const SC_BC_SCALE_MAX* = cint(38) +const SC_BC_STRING_MAX* = cint(39) +const SC_CHILD_MAX* = cint(1) +const SC_CLK_TCK* = cint(2) +const SC_CLOCK_SELECTION* = cint(137) +const SC_COLL_WEIGHTS_MAX* = cint(40) +const SC_CPUTIME* = cint(138) +const SC_DELAYTIMER_MAX* = cint(26) +const SC_EXPR_NEST_MAX* = cint(42) +const SC_FSYNC* = cint(15) +const SC_GETGR_R_SIZE_MAX* = cint(69) +const SC_GETPW_R_SIZE_MAX* = cint(70) +const SC_HOST_NAME_MAX* = cint(180) +const SC_IOV_MAX* = cint(60) +const SC_IPV6* = cint(235) +const SC_JOB_CONTROL* = cint(7) +const SC_LINE_MAX* = cint(43) +const SC_LOGIN_NAME_MAX* = cint(71) +const SC_MAPPED_FILES* = cint(16) +const SC_MEMLOCK* = cint(17) +const SC_MEMLOCK_RANGE* = cint(18) +const SC_MEMORY_PROTECTION* = cint(19) +const SC_MESSAGE_PASSING* = cint(20) +const SC_MONOTONIC_CLOCK* = cint(149) +const SC_MQ_OPEN_MAX* = cint(27) +const SC_MQ_PRIO_MAX* = cint(28) +const SC_NGROUPS_MAX* = cint(3) +const SC_OPEN_MAX* = cint(4) +const SC_PAGE_SIZE* = cint(30) +const SC_PRIORITIZED_IO* = cint(13) +const SC_PRIORITY_SCHEDULING* = cint(10) +const SC_RAW_SOCKETS* = cint(236) +const SC_RE_DUP_MAX* = cint(44) +const SC_READER_WRITER_LOCKS* = cint(153) +const SC_REALTIME_SIGNALS* = cint(9) +const SC_REGEXP* = cint(155) +const SC_RTSIG_MAX* = cint(31) +const SC_SAVED_IDS* = cint(8) +const SC_SEM_NSEMS_MAX* = cint(32) +const SC_SEM_VALUE_MAX* = cint(33) +const SC_SEMAPHORES* = cint(21) +const SC_SHARED_MEMORY_OBJECTS* = cint(22) +const SC_SHELL* = cint(157) +const SC_SIGQUEUE_MAX* = cint(34) +const SC_SPAWN* = cint(159) +const SC_SPIN_LOCKS* = cint(154) +const SC_SPORADIC_SERVER* = cint(160) +const SC_SS_REPL_MAX* = cint(241) +const SC_STREAM_MAX* = cint(5) +const SC_SYMLOOP_MAX* = cint(173) +const SC_SYNCHRONIZED_IO* = cint(14) +const SC_THREAD_ATTR_STACKADDR* = cint(77) +const SC_THREAD_ATTR_STACKSIZE* = cint(78) +const SC_THREAD_CPUTIME* = cint(139) +const SC_THREAD_DESTRUCTOR_ITERATIONS* = cint(73) +const SC_THREAD_KEYS_MAX* = cint(74) +const SC_THREAD_PRIO_INHERIT* = cint(80) +const SC_THREAD_PRIO_PROTECT* = cint(81) +const SC_THREAD_PRIORITY_SCHEDULING* = cint(79) +const SC_THREAD_PROCESS_SHARED* = cint(82) +const SC_THREAD_SAFE_FUNCTIONS* = cint(68) +const SC_THREAD_SPORADIC_SERVER* = cint(161) +const SC_THREAD_STACK_MIN* = cint(75) +const SC_THREAD_THREADS_MAX* = cint(76) +const SC_THREADS* = cint(67) +const SC_TIMEOUTS* = cint(164) +const SC_TIMER_MAX* = cint(35) +const SC_TIMERS* = cint(11) +const SC_TRACE* = cint(181) +const SC_TRACE_EVENT_FILTER* = cint(182) +const SC_TRACE_EVENT_NAME_MAX* = cint(242) +const SC_TRACE_INHERIT* = cint(183) +const SC_TRACE_LOG* = cint(184) +const SC_TRACE_NAME_MAX* = cint(243) +const SC_TRACE_SYS_MAX* = cint(244) +const SC_TRACE_USER_EVENT_MAX* = cint(245) +const SC_TTY_NAME_MAX* = cint(72) +const SC_TYPED_MEMORY_OBJECTS* = cint(165) +const SC_TZNAME_MAX* = cint(6) +const SC_V6_ILP32_OFF32* = cint(176) +const SC_V6_ILP32_OFFBIG* = cint(177) +const SC_V6_LP64_OFF64* = cint(178) +const SC_V6_LPBIG_OFFBIG* = cint(179) +const SC_VERSION* = cint(29) +const SC_XBS5_ILP32_OFF32* = cint(125) +const SC_XBS5_ILP32_OFFBIG* = cint(126) +const SC_XBS5_LP64_OFF64* = cint(127) +const SC_XBS5_LPBIG_OFFBIG* = cint(128) +const SC_XOPEN_CRYPT* = cint(92) +const SC_XOPEN_ENH_I18N* = cint(93) +const SC_XOPEN_LEGACY* = cint(129) +const SC_XOPEN_REALTIME* = cint(130) +const SC_XOPEN_REALTIME_THREADS* = cint(131) +const SC_XOPEN_SHM* = cint(94) +const SC_XOPEN_STREAMS* = cint(246) +const SC_XOPEN_UNIX* = cint(91) +const SC_XOPEN_VERSION* = cint(89) +const SC_NPROCESSORS_ONLN* = cint(84) +const SEEK_SET* = cint(0) +const SEEK_CUR* = cint(1) +const SEEK_END* = cint(2) diff --git a/lib/posix/posix_other.nim b/lib/posix/posix_other.nim new file mode 100644 index 000000000..b1cc244b7 --- /dev/null +++ b/lib/posix/posix_other.nim @@ -0,0 +1,628 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2012 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +{.deadCodeElim:on.} + +from times import Time + +const + hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays + hasAioH = defined(linux) + +when defined(linux): + # On Linux: + # timer_{create,delete,settime,gettime}, + # clock_{getcpuclockid, getres, gettime, nanosleep, settime} lives in librt + {.passL: "-lrt".} +when defined(solaris): + # On Solaris hstrerror lives in libresolv + {.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 + Timespec* {.importc: "struct timespec", + header: "<time.h>", final, pure.} = object ## struct timespec + tv_sec*: Time ## Seconds. + tv_nsec*: int ## Nanoseconds. + + Dirent* {.importc: "struct dirent", + header: "<dirent.h>", final, pure.} = object ## dirent_t struct + d_ino*: Ino ## File serial number. + when defined(dragonfly): + # DragonflyBSD doesn't have `d_reclen` field. + d_type*: uint8 + elif defined(linux) or defined(macosx) or defined(freebsd) or + defined(netbsd) or defined(openbsd): + d_reclen*: cshort ## Length of this record. (not POSIX) + 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_name*: array[0..255, char] ## Name of entry. + + Tflock* {.importc: "struct flock", final, pure, + header: "<fcntl.h>".} = object ## flock type + l_type*: cshort ## Type of lock; F_RDLCK, F_WRLCK, F_UNLCK. + l_whence*: cshort ## Flag for starting offset. + l_start*: Off ## Relative offset in bytes. + l_len*: Off ## Size; if 0 then until EOF. + l_pid*: Pid ## Process ID of the process holding the lock; + ## returned with F_GETLK. + + FTW* {.importc: "struct FTW", header: "<ftw.h>", final, pure.} = object + base*: cint + level*: cint + + Glob* {.importc: "glob_t", header: "<glob.h>", + final, pure.} = object ## glob_t + gl_pathc*: int ## Count of paths matched by pattern. + gl_pathv*: cstringArray ## Pointer to a list of matched pathnames. + gl_offs*: int ## Slots to reserve at the beginning of gl_pathv. + + Group* {.importc: "struct group", header: "<grp.h>", + final, pure.} = object ## struct group + gr_name*: cstring ## The name of the group. + gr_gid*: Gid ## Numerical group ID. + gr_mem*: cstringArray ## Pointer to a null-terminated array of character + ## pointers to member names. + + Iconv* {.importc: "iconv_t", header: "<iconv.h>", final, pure.} = + object ## Identifies the conversion from one codeset to another. + + Lconv* {.importc: "struct lconv", header: "<locale.h>", final, + pure.} = object + currency_symbol*: cstring + decimal_point*: cstring + frac_digits*: char + grouping*: cstring + int_curr_symbol*: cstring + int_frac_digits*: char + int_n_cs_precedes*: char + int_n_sep_by_space*: char + int_n_sign_posn*: char + int_p_cs_precedes*: char + int_p_sep_by_space*: char + int_p_sign_posn*: char + mon_decimal_point*: cstring + mon_grouping*: cstring + mon_thousands_sep*: cstring + negative_sign*: cstring + n_cs_precedes*: char + n_sep_by_space*: char + n_sign_posn*: char + positive_sign*: cstring + p_cs_precedes*: char + p_sep_by_space*: char + p_sign_posn*: char + thousands_sep*: cstring + + Mqd* {.importc: "mqd_t", header: "<mqueue.h>", final, pure.} = object + MqAttr* {.importc: "struct mq_attr", + header: "<mqueue.h>", + final, pure.} = object ## message queue attribute + mq_flags*: int ## Message queue flags. + mq_maxmsg*: int ## Maximum number of messages. + mq_msgsize*: int ## Maximum message size. + mq_curmsgs*: int ## Number of messages currently queued. + + Passwd* {.importc: "struct passwd", header: "<pwd.h>", + final, pure.} = object ## struct passwd + pw_name*: cstring ## User's login name. + pw_uid*: Uid ## Numerical user ID. + pw_gid*: Gid ## Numerical group ID. + pw_dir*: cstring ## Initial working directory. + pw_shell*: cstring ## Program to use as shell. + + Blkcnt* {.importc: "blkcnt_t", header: "<sys/types.h>".} = int + ## used for file block counts + Blksize* {.importc: "blksize_t", header: "<sys/types.h>".} = int + ## used for block sizes + Clock* {.importc: "clock_t", header: "<sys/types.h>".} = int + ClockId* {.importc: "clockid_t", header: "<sys/types.h>".} = int + Dev* {.importc: "dev_t", header: "<sys/types.h>".} = int + Fsblkcnt* {.importc: "fsblkcnt_t", header: "<sys/types.h>".} = int + Fsfilcnt* {.importc: "fsfilcnt_t", header: "<sys/types.h>".} = int + Gid* {.importc: "gid_t", header: "<sys/types.h>".} = int + 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 + 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>".} = int + Pthread_attr* {.importc: "pthread_attr_t", header: "<sys/types.h>".} = int + Pthread_barrier* {.importc: "pthread_barrier_t", + header: "<sys/types.h>".} = int + Pthread_barrierattr* {.importc: "pthread_barrierattr_t", + header: "<sys/types.h>".} = int + Pthread_cond* {.importc: "pthread_cond_t", header: "<sys/types.h>".} = int + Pthread_condattr* {.importc: "pthread_condattr_t", + header: "<sys/types.h>".} = int + Pthread_key* {.importc: "pthread_key_t", header: "<sys/types.h>".} = int + Pthread_mutex* {.importc: "pthread_mutex_t", header: "<sys/types.h>".} = int + Pthread_mutexattr* {.importc: "pthread_mutexattr_t", + header: "<sys/types.h>".} = int + Pthread_once* {.importc: "pthread_once_t", header: "<sys/types.h>".} = int + Pthread_rwlock* {.importc: "pthread_rwlock_t", + header: "<sys/types.h>".} = int + Pthread_rwlockattr* {.importc: "pthread_rwlockattr_t", + header: "<sys/types.h>".} = int + Pthread_spinlock* {.importc: "pthread_spinlock_t", + header: "<sys/types.h>".} = int + Pthread* {.importc: "pthread_t", header: "<sys/types.h>".} = int + Suseconds* {.importc: "suseconds_t", header: "<sys/types.h>".} = int + #Ttime* {.importc: "time_t", header: "<sys/types.h>".} = int + Timer* {.importc: "timer_t", header: "<sys/types.h>".} = int + Trace_attr* {.importc: "trace_attr_t", header: "<sys/types.h>".} = int + Trace_event_id* {.importc: "trace_event_id_t", + header: "<sys/types.h>".} = int + Trace_event_set* {.importc: "trace_event_set_t", + header: "<sys/types.h>".} = int + Trace_id* {.importc: "trace_id_t", header: "<sys/types.h>".} = int + Uid* {.importc: "uid_t", header: "<sys/types.h>".} = int + Useconds* {.importc: "useconds_t", header: "<sys/types.h>".} = int + + Utsname* {.importc: "struct utsname", + header: "<sys/utsname.h>", + final, pure.} = object ## struct utsname + sysname*, ## Name of this implementation of the operating system. + nodename*, ## Name of this node within the communications + ## network to which this node is attached, if any. + release*, ## Current release level of this implementation. + version*, ## Current version level of this release. + machine*: array[0..255, char] ## Name of the hardware type on which the + ## system is running. + + Sem* {.importc: "sem_t", header: "<semaphore.h>", final, pure.} = object + Ipc_perm* {.importc: "struct ipc_perm", + header: "<sys/ipc.h>", final, pure.} = object ## struct ipc_perm + uid*: Uid ## Owner's user ID. + gid*: Gid ## Owner's group ID. + cuid*: Uid ## Creator's user ID. + cgid*: Gid ## Creator's group ID. + mode*: Mode ## Read/write permission. + + Stat* {.importc: "struct stat", + header: "<sys/stat.h>", final, pure.} = object ## struct stat + st_dev*: Dev ## Device ID of device containing file. + st_ino*: Ino ## File serial number. + st_mode*: Mode ## Mode of file (see below). + st_nlink*: Nlink ## Number of hard links to the file. + st_uid*: Uid ## User ID of file. + st_gid*: Gid ## Group ID of file. + st_rdev*: Dev ## Device ID (if file is character or block special). + st_size*: Off ## For regular files, the file size in bytes. + ## For symbolic links, the length in bytes of the + ## pathname contained in the symbolic link. + ## For a shared memory object, the length in bytes. + ## For a typed memory object, the length in bytes. + ## For other file types, the use of this field is + ## unspecified. + when defined(macosx): + st_atime*: Time ## Time of last access. + st_mtime*: Time ## Time of last data modification. + st_ctime*: Time ## Time of last status change. + else: + st_atim*: Timespec ## Time of last access. + st_mtim*: Timespec ## Time of last data modification. + st_ctim*: Timespec ## Time of last status change. + st_blksize*: Blksize ## A file system-specific preferred I/O block size + ## for this object. In some file system types, this + ## may vary from file to file. + st_blocks*: Blkcnt ## Number of blocks allocated for this object. + + + Statvfs* {.importc: "struct statvfs", header: "<sys/statvfs.h>", + final, pure.} = object ## struct statvfs + f_bsize*: int ## File system block size. + f_frsize*: int ## Fundamental file system block size. + f_blocks*: Fsblkcnt ## Total number of blocks on file system + ## in units of f_frsize. + f_bfree*: Fsblkcnt ## Total number of free blocks. + f_bavail*: Fsblkcnt ## Number of free blocks available to + ## non-privileged process. + f_files*: Fsfilcnt ## Total number of file serial numbers. + f_ffree*: Fsfilcnt ## Total number of free file serial numbers. + f_favail*: Fsfilcnt ## Number of file serial numbers available to + ## non-privileged process. + f_fsid*: int ## File system ID. + f_flag*: int ## Bit mask of f_flag values. + f_namemax*: int ## Maximum filename length. + + Posix_typed_mem_info* {.importc: "struct posix_typed_mem_info", + header: "<sys/mman.h>", final, pure.} = object + posix_tmi_length*: int + + Tm* {.importc: "struct tm", header: "<time.h>", + final, pure.} = object ## struct tm + tm_sec*: cint ## Seconds [0,60]. + tm_min*: cint ## Minutes [0,59]. + tm_hour*: cint ## Hour [0,23]. + tm_mday*: cint ## Day of month [1,31]. + tm_mon*: cint ## Month of year [0,11]. + tm_year*: cint ## Years since 1900. + tm_wday*: cint ## Day of week [0,6] (Sunday =0). + tm_yday*: cint ## Day of year [0,365]. + tm_isdst*: cint ## Daylight Savings flag. + Itimerspec* {.importc: "struct itimerspec", header: "<time.h>", + final, pure.} = object ## struct itimerspec + it_interval*: Timespec ## Timer period. + it_value*: Timespec ## Timer expiration. + + Sig_atomic* {.importc: "sig_atomic_t", header: "<signal.h>".} = cint + ## Possibly volatile-qualified integer type of an object that can be + ## accessed as an atomic entity, even in the presence of asynchronous + ## interrupts. + Sigset* {.importc: "sigset_t", header: "<signal.h>", final, pure.} = object + + SigEvent* {.importc: "struct sigevent", + header: "<signal.h>", final, pure.} = object ## struct sigevent + sigev_notify*: cint ## Notification 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. + + SigVal* {.importc: "union sigval", + header: "<signal.h>", final, pure.} = object ## struct sigval + sival_ptr*: pointer ## pointer signal value; + ## integer signal value not defined! + Sigaction* {.importc: "struct sigaction", + header: "<signal.h>", final, pure.} = object ## struct sigaction + sa_handler*: proc (x: cint) {.noconv.} ## Pointer to a signal-catching + ## function or one of the macros + ## SIG_IGN or SIG_DFL. + sa_mask*: Sigset ## Set of signals to be blocked during execution of + ## the signal handling function. + sa_flags*: cint ## Special flags. + sa_sigaction*: proc (x: cint, y: ptr SigInfo, z: pointer) {.noconv.} + + Stack* {.importc: "stack_t", + header: "<signal.h>", final, pure.} = object ## stack_t + ss_sp*: pointer ## Stack base or pointer. + ss_size*: int ## Stack size. + ss_flags*: cint ## Flags. + + SigStack* {.importc: "struct sigstack", + header: "<signal.h>", final, pure.} = object ## struct sigstack + ss_onstack*: cint ## Non-zero when signal stack is in use. + ss_sp*: pointer ## Signal stack pointer. + + SigInfo* {.importc: "siginfo_t", + header: "<signal.h>", final, pure.} = object ## siginfo_t + si_signo*: cint ## Signal number. + si_code*: cint ## Signal code. + si_errno*: cint ## If non-zero, an errno value associated with + ## this signal, as defined in <errno.h>. + si_pid*: Pid ## Sending process ID. + si_uid*: Uid ## Real user ID of sending process. + si_addr*: pointer ## Address of faulting instruction. + si_status*: cint ## Exit value or signal. + si_band*: int ## Band event for SIGPOLL. + si_value*: SigVal ## Signal value. + + Nl_item* {.importc: "nl_item", header: "<nl_types.h>".} = cint + Nl_catd* {.importc: "nl_catd", header: "<nl_types.h>".} = cint + + Sched_param* {.importc: "struct sched_param", + header: "<sched.h>", + final, pure.} = object ## struct sched_param + sched_priority*: cint + sched_ss_low_priority*: cint ## Low scheduling priority for + ## sporadic server. + sched_ss_repl_period*: Timespec ## Replenishment period for + ## sporadic server. + sched_ss_init_budget*: Timespec ## Initial budget for sporadic server. + sched_ss_max_repl*: cint ## Maximum pending replenishments for + ## sporadic server. + + Timeval* {.importc: "struct timeval", header: "<sys/select.h>", + final, pure.} = object ## struct timeval + tv_sec*: int ## Seconds. + tv_usec*: int ## Microseconds. + TFdSet* {.importc: "fd_set", header: "<sys/select.h>", + final, pure.} = object + Mcontext* {.importc: "mcontext_t", header: "<ucontext.h>", + final, pure.} = object + Ucontext* {.importc: "ucontext_t", header: "<ucontext.h>", + final, pure.} = object ## ucontext_t + uc_link*: ptr Ucontext ## Pointer to the context that is resumed + ## when this context returns. + uc_sigmask*: Sigset ## The set of signals that are blocked when this + ## context is active. + 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>", + final, pure.} = object ## struct aiocb + aio_fildes*: cint ## File descriptor. + aio_offset*: Off ## File offset. + aio_buf*: pointer ## Location of buffer. + aio_nbytes*: int ## Length of transfer. + aio_reqprio*: cint ## Request priority offset. + aio_sigevent*: SigEvent ## Signal number and value. + aio_lio_opcode: cint ## Operation to be performed. + +when hasSpawnH: + type + Tposix_spawnattr* {.importc: "posix_spawnattr_t", + header: "<spawn.h>", final, pure.} = object + Tposix_spawn_file_actions* {.importc: "posix_spawn_file_actions_t", + header: "<spawn.h>", final, pure.} = object + +when defined(linux): + # from sys/un.h + const Sockaddr_un_path_length* = 108 +else: + # 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 + + 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_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 + + Sockaddr_storage* {.importc: "struct sockaddr_storage", + header: "<sys/socket.h>", + pure, final.} = object ## struct sockaddr_storage + ss_family*: TSa_Family ## Address family. + + Tif_nameindex* {.importc: "struct if_nameindex", final, + pure, header: "<net/if.h>".} = object ## struct if_nameindex + if_index*: cint ## Numeric index of the interface. + if_name*: cstring ## Null-terminated name of the interface. + + + 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. + + 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_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_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_level*: cint ## Originating protocol. + cmsg_type*: cint ## Protocol-specific type. + + TLinger* {.importc: "struct linger", pure, final, + header: "<sys/socket.h>".} = object ## struct linger + l_onoff*: cint ## Indicates whether linger option is enabled. + l_linger*: cint ## Linger time, in seconds. + + InPort* = uint16 + InAddrScalar* = uint32 + + InAddrT* {.importc: "in_addr_t", pure, final, + header: "<netinet/in.h>".} = uint32 + + InAddr* {.importc: "struct in_addr", pure, final, + header: "<netinet/in.h>".} = object ## struct in_addr + s_addr*: InAddrScalar + + Sockaddr_in* {.importc: "struct sockaddr_in", pure, final, + header: "<netinet/in.h>".} = object ## struct sockaddr_in + sin_family*: TSa_Family ## AF_INET. + sin_port*: InPort ## Port number. + sin_addr*: InAddr ## IP address. + + In6Addr* {.importc: "struct in6_addr", pure, final, + header: "<netinet/in.h>".} = object ## struct in6_addr + s6_addr*: array[0..15, char] + + Sockaddr_in6* {.importc: "struct sockaddr_in6", pure, final, + header: "<netinet/in.h>".} = object ## struct sockaddr_in6 + sin6_family*: TSa_Family ## AF_INET6. + sin6_port*: InPort ## Port number. + sin6_flowinfo*: int32 ## IPv6 traffic class and flow information. + sin6_addr*: In6Addr ## IPv6 address. + sin6_scope_id*: int32 ## Set of interfaces for a scope. + + Tipv6_mreq* {.importc: "struct ipv6_mreq", pure, final, + header: "<netinet/in.h>".} = object ## struct ipv6_mreq + ipv6mr_multiaddr*: In6Addr ## IPv6 multicast address. + ipv6mr_interface*: cint ## Interface index. + + Hostent* {.importc: "struct hostent", pure, final, + header: "<netdb.h>".} = object ## struct hostent + h_name*: cstring ## Official name of the host. + h_aliases*: cstringArray ## A pointer to an array of pointers to + ## alternative host names, terminated by a + ## null pointer. + h_addrtype*: cint ## Address type. + h_length*: cint ## The length, in bytes, of the address. + h_addr_list*: cstringArray ## A pointer to an array of pointers to network + ## addresses (in network byte order) for the + ## host, terminated by a null pointer. + + Tnetent* {.importc: "struct netent", pure, final, + header: "<netdb.h>".} = object ## struct netent + n_name*: cstring ## Official, fully-qualified (including the + ## domain) name of the host. + n_aliases*: cstringArray ## A pointer to an array of pointers to + ## alternative network names, terminated by a + ## null pointer. + n_addrtype*: cint ## The address type of the network. + n_net*: int32 ## The network number, in host byte order. + + Protoent* {.importc: "struct protoent", pure, final, + header: "<netdb.h>".} = object ## struct protoent + p_name*: cstring ## Official name of the protocol. + p_aliases*: cstringArray ## A pointer to an array of pointers to + ## alternative protocol names, terminated by + ## a null pointer. + p_proto*: cint ## The protocol number. + + Servent* {.importc: "struct servent", pure, final, + header: "<netdb.h>".} = object ## struct servent + s_name*: cstring ## Official name of the service. + s_aliases*: cstringArray ## A pointer to an array of pointers to + ## alternative service names, terminated by + ## a null pointer. + s_port*: cint ## The port number at which the service + ## resides, in network byte order. + s_proto*: cstring ## The name of the protocol to use when + ## contacting the service. + + AddrInfo* {.importc: "struct addrinfo", pure, final, + header: "<netdb.h>".} = object ## struct addrinfo + ai_flags*: cint ## Input flags. + 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_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].} + +var + errno* {.importc, header: "<errno.h>".}: cint ## error variable + h_errno* {.importc, header: "<netdb.h>".}: cint + daylight* {.importc, header: "<time.h>".}: cint + timezone* {.importc, header: "<time.h>".}: int + +# Regenerate using detect.nim! +include posix_other_consts + +when defined(linux): + var + MAP_POPULATE* {.importc, header: "<sys/mman.h>".}: cint + ## Populate (prefault) page tables for a mapping. +else: + var + MAP_POPULATE*: cint = 0 + +when defined(linux) or defined(nimdoc): + when defined(alpha) or defined(mips) or defined(parisc) or + defined(sparc) 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) +else: + var SO_REUSEPORT* {.importc, header: "<sys/socket.h>".}: cint + +when defined(macosx): + # 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 + const + MSG_NOSIGNAL* = 0'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 hasSpawnH: + when defined(linux): + # better be safe than sorry; Linux has this flag, macosx doesn't, don't + # know about the other OSes + + # 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 + # 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) +proc WTERMSIG*(s: cint): cint {.importc, header: "<sys/wait.h>".} + ## Termination signal, iff WIFSIGNALED(s) +proc WSTOPSIG*(s: cint): cint {.importc, header: "<sys/wait.h>".} + ## Stop signal, iff 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>".} + ## True if child exited due to uncaught signal. +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. diff --git a/lib/posix/posix_other_consts.nim b/lib/posix/posix_other_consts.nim new file mode 100644 index 000000000..f2a71d1bd --- /dev/null +++ b/lib/posix/posix_other_consts.nim @@ -0,0 +1,723 @@ +# Generated by detect.nim + +# <aio.h> +var AIO_ALLDONE* {.importc: "AIO_ALLDONE", header: "<aio.h>".}: cint +var AIO_CANCELED* {.importc: "AIO_CANCELED", header: "<aio.h>".}: cint +var AIO_NOTCANCELED* {.importc: "AIO_NOTCANCELED", header: "<aio.h>".}: cint +var LIO_NOP* {.importc: "LIO_NOP", header: "<aio.h>".}: cint +var LIO_NOWAIT* {.importc: "LIO_NOWAIT", header: "<aio.h>".}: cint +var LIO_READ* {.importc: "LIO_READ", header: "<aio.h>".}: cint +var LIO_WAIT* {.importc: "LIO_WAIT", header: "<aio.h>".}: cint +var LIO_WRITE* {.importc: "LIO_WRITE", header: "<aio.h>".}: cint + +# <dlfcn.h> +var RTLD_LAZY* {.importc: "RTLD_LAZY", header: "<dlfcn.h>".}: cint +var RTLD_NOW* {.importc: "RTLD_NOW", header: "<dlfcn.h>".}: cint +var RTLD_GLOBAL* {.importc: "RTLD_GLOBAL", header: "<dlfcn.h>".}: cint +var RTLD_LOCAL* {.importc: "RTLD_LOCAL", header: "<dlfcn.h>".}: cint + +# <errno.h> +var E2BIG* {.importc: "E2BIG", header: "<errno.h>".}: cint +var EACCES* {.importc: "EACCES", header: "<errno.h>".}: cint +var EADDRINUSE* {.importc: "EADDRINUSE", header: "<errno.h>".}: cint +var EADDRNOTAVAIL* {.importc: "EADDRNOTAVAIL", header: "<errno.h>".}: cint +var EAFNOSUPPORT* {.importc: "EAFNOSUPPORT", header: "<errno.h>".}: cint +var EAGAIN* {.importc: "EAGAIN", header: "<errno.h>".}: cint +var EALREADY* {.importc: "EALREADY", header: "<errno.h>".}: cint +var EBADF* {.importc: "EBADF", header: "<errno.h>".}: cint +var EBADMSG* {.importc: "EBADMSG", header: "<errno.h>".}: cint +var EBUSY* {.importc: "EBUSY", header: "<errno.h>".}: cint +var ECANCELED* {.importc: "ECANCELED", header: "<errno.h>".}: cint +var ECHILD* {.importc: "ECHILD", header: "<errno.h>".}: cint +var ECONNABORTED* {.importc: "ECONNABORTED", header: "<errno.h>".}: cint +var ECONNREFUSED* {.importc: "ECONNREFUSED", header: "<errno.h>".}: cint +var ECONNRESET* {.importc: "ECONNRESET", header: "<errno.h>".}: cint +var EDEADLK* {.importc: "EDEADLK", header: "<errno.h>".}: cint +var EDESTADDRREQ* {.importc: "EDESTADDRREQ", header: "<errno.h>".}: cint +var EDOM* {.importc: "EDOM", header: "<errno.h>".}: cint +var EDQUOT* {.importc: "EDQUOT", header: "<errno.h>".}: cint +var EEXIST* {.importc: "EEXIST", header: "<errno.h>".}: cint +var EFAULT* {.importc: "EFAULT", header: "<errno.h>".}: cint +var EFBIG* {.importc: "EFBIG", header: "<errno.h>".}: cint +var EHOSTUNREACH* {.importc: "EHOSTUNREACH", header: "<errno.h>".}: cint +var EIDRM* {.importc: "EIDRM", header: "<errno.h>".}: cint +var EILSEQ* {.importc: "EILSEQ", header: "<errno.h>".}: cint +var EINPROGRESS* {.importc: "EINPROGRESS", header: "<errno.h>".}: cint +var EINTR* {.importc: "EINTR", header: "<errno.h>".}: cint +var EINVAL* {.importc: "EINVAL", header: "<errno.h>".}: cint +var EIO* {.importc: "EIO", header: "<errno.h>".}: cint +var EISCONN* {.importc: "EISCONN", header: "<errno.h>".}: cint +var EISDIR* {.importc: "EISDIR", header: "<errno.h>".}: cint +var ELOOP* {.importc: "ELOOP", header: "<errno.h>".}: cint +var EMFILE* {.importc: "EMFILE", header: "<errno.h>".}: cint +var EMLINK* {.importc: "EMLINK", header: "<errno.h>".}: cint +var EMSGSIZE* {.importc: "EMSGSIZE", header: "<errno.h>".}: cint +var EMULTIHOP* {.importc: "EMULTIHOP", header: "<errno.h>".}: cint +var ENAMETOOLONG* {.importc: "ENAMETOOLONG", header: "<errno.h>".}: cint +var ENETDOWN* {.importc: "ENETDOWN", header: "<errno.h>".}: cint +var ENETRESET* {.importc: "ENETRESET", header: "<errno.h>".}: cint +var ENETUNREACH* {.importc: "ENETUNREACH", header: "<errno.h>".}: cint +var ENFILE* {.importc: "ENFILE", header: "<errno.h>".}: cint +var ENOBUFS* {.importc: "ENOBUFS", header: "<errno.h>".}: cint +var ENODATA* {.importc: "ENODATA", header: "<errno.h>".}: cint +var ENODEV* {.importc: "ENODEV", header: "<errno.h>".}: cint +var ENOENT* {.importc: "ENOENT", header: "<errno.h>".}: cint +var ENOEXEC* {.importc: "ENOEXEC", header: "<errno.h>".}: cint +var ENOLCK* {.importc: "ENOLCK", header: "<errno.h>".}: cint +var ENOLINK* {.importc: "ENOLINK", header: "<errno.h>".}: cint +var ENOMEM* {.importc: "ENOMEM", header: "<errno.h>".}: cint +var ENOMSG* {.importc: "ENOMSG", header: "<errno.h>".}: cint +var ENOPROTOOPT* {.importc: "ENOPROTOOPT", header: "<errno.h>".}: cint +var ENOSPC* {.importc: "ENOSPC", header: "<errno.h>".}: cint +var ENOSR* {.importc: "ENOSR", header: "<errno.h>".}: cint +var ENOSTR* {.importc: "ENOSTR", header: "<errno.h>".}: cint +var ENOSYS* {.importc: "ENOSYS", header: "<errno.h>".}: cint +var ENOTCONN* {.importc: "ENOTCONN", header: "<errno.h>".}: cint +var ENOTDIR* {.importc: "ENOTDIR", header: "<errno.h>".}: cint +var ENOTEMPTY* {.importc: "ENOTEMPTY", header: "<errno.h>".}: cint +var ENOTSOCK* {.importc: "ENOTSOCK", header: "<errno.h>".}: cint +var ENOTSUP* {.importc: "ENOTSUP", header: "<errno.h>".}: cint +var ENOTTY* {.importc: "ENOTTY", header: "<errno.h>".}: cint +var ENXIO* {.importc: "ENXIO", header: "<errno.h>".}: cint +var EOPNOTSUPP* {.importc: "EOPNOTSUPP", header: "<errno.h>".}: cint +var EOVERFLOW* {.importc: "EOVERFLOW", header: "<errno.h>".}: cint +var EPERM* {.importc: "EPERM", header: "<errno.h>".}: cint +var EPIPE* {.importc: "EPIPE", header: "<errno.h>".}: cint +var EPROTO* {.importc: "EPROTO", header: "<errno.h>".}: cint +var EPROTONOSUPPORT* {.importc: "EPROTONOSUPPORT", header: "<errno.h>".}: cint +var EPROTOTYPE* {.importc: "EPROTOTYPE", header: "<errno.h>".}: cint +var ERANGE* {.importc: "ERANGE", header: "<errno.h>".}: cint +var EROFS* {.importc: "EROFS", header: "<errno.h>".}: cint +var ESPIPE* {.importc: "ESPIPE", header: "<errno.h>".}: cint +var ESRCH* {.importc: "ESRCH", header: "<errno.h>".}: cint +var ESTALE* {.importc: "ESTALE", header: "<errno.h>".}: cint +var ETIME* {.importc: "ETIME", header: "<errno.h>".}: cint +var ETIMEDOUT* {.importc: "ETIMEDOUT", header: "<errno.h>".}: cint +var ETXTBSY* {.importc: "ETXTBSY", header: "<errno.h>".}: cint +var EWOULDBLOCK* {.importc: "EWOULDBLOCK", header: "<errno.h>".}: cint +var EXDEV* {.importc: "EXDEV", header: "<errno.h>".}: cint + +# <fcntl.h> +var F_DUPFD* {.importc: "F_DUPFD", header: "<fcntl.h>".}: cint +var F_GETFD* {.importc: "F_GETFD", header: "<fcntl.h>".}: cint +var F_SETFD* {.importc: "F_SETFD", header: "<fcntl.h>".}: cint +var F_GETFL* {.importc: "F_GETFL", header: "<fcntl.h>".}: cint +var F_SETFL* {.importc: "F_SETFL", header: "<fcntl.h>".}: cint +var F_GETLK* {.importc: "F_GETLK", header: "<fcntl.h>".}: cint +var F_SETLK* {.importc: "F_SETLK", header: "<fcntl.h>".}: cint +var F_SETLKW* {.importc: "F_SETLKW", header: "<fcntl.h>".}: cint +var F_GETOWN* {.importc: "F_GETOWN", header: "<fcntl.h>".}: cint +var F_SETOWN* {.importc: "F_SETOWN", header: "<fcntl.h>".}: cint +var FD_CLOEXEC* {.importc: "FD_CLOEXEC", header: "<fcntl.h>".}: cint +var F_RDLCK* {.importc: "F_RDLCK", header: "<fcntl.h>".}: cint +var F_UNLCK* {.importc: "F_UNLCK", header: "<fcntl.h>".}: cint +var F_WRLCK* {.importc: "F_WRLCK", header: "<fcntl.h>".}: cint +var O_CREAT* {.importc: "O_CREAT", header: "<fcntl.h>".}: cint +var O_EXCL* {.importc: "O_EXCL", header: "<fcntl.h>".}: cint +var O_NOCTTY* {.importc: "O_NOCTTY", header: "<fcntl.h>".}: cint +var O_TRUNC* {.importc: "O_TRUNC", header: "<fcntl.h>".}: cint +var O_APPEND* {.importc: "O_APPEND", header: "<fcntl.h>".}: cint +var O_DSYNC* {.importc: "O_DSYNC", header: "<fcntl.h>".}: cint +var O_NONBLOCK* {.importc: "O_NONBLOCK", header: "<fcntl.h>".}: cint +var O_RSYNC* {.importc: "O_RSYNC", header: "<fcntl.h>".}: cint +var O_SYNC* {.importc: "O_SYNC", header: "<fcntl.h>".}: cint +var O_ACCMODE* {.importc: "O_ACCMODE", header: "<fcntl.h>".}: cint +var O_RDONLY* {.importc: "O_RDONLY", header: "<fcntl.h>".}: cint +var O_RDWR* {.importc: "O_RDWR", header: "<fcntl.h>".}: cint +var O_WRONLY* {.importc: "O_WRONLY", header: "<fcntl.h>".}: cint +var POSIX_FADV_NORMAL* {.importc: "POSIX_FADV_NORMAL", header: "<fcntl.h>".}: cint +var POSIX_FADV_SEQUENTIAL* {.importc: "POSIX_FADV_SEQUENTIAL", header: "<fcntl.h>".}: cint +var POSIX_FADV_RANDOM* {.importc: "POSIX_FADV_RANDOM", header: "<fcntl.h>".}: cint +var POSIX_FADV_WILLNEED* {.importc: "POSIX_FADV_WILLNEED", header: "<fcntl.h>".}: cint +var POSIX_FADV_DONTNEED* {.importc: "POSIX_FADV_DONTNEED", header: "<fcntl.h>".}: cint +var POSIX_FADV_NOREUSE* {.importc: "POSIX_FADV_NOREUSE", header: "<fcntl.h>".}: cint + +# <fenv.h> +var FE_DIVBYZERO* {.importc: "FE_DIVBYZERO", header: "<fenv.h>".}: cint +var FE_INEXACT* {.importc: "FE_INEXACT", header: "<fenv.h>".}: cint +var FE_INVALID* {.importc: "FE_INVALID", header: "<fenv.h>".}: cint +var FE_OVERFLOW* {.importc: "FE_OVERFLOW", header: "<fenv.h>".}: cint +var FE_UNDERFLOW* {.importc: "FE_UNDERFLOW", header: "<fenv.h>".}: cint +var FE_ALL_EXCEPT* {.importc: "FE_ALL_EXCEPT", header: "<fenv.h>".}: cint +var FE_DOWNWARD* {.importc: "FE_DOWNWARD", header: "<fenv.h>".}: cint +var FE_TONEAREST* {.importc: "FE_TONEAREST", header: "<fenv.h>".}: cint +var FE_TOWARDZERO* {.importc: "FE_TOWARDZERO", header: "<fenv.h>".}: cint +var FE_UPWARD* {.importc: "FE_UPWARD", header: "<fenv.h>".}: cint +var FE_DFL_ENV* {.importc: "FE_DFL_ENV", header: "<fenv.h>".}: cint + +# <fmtmsg.h> +var MM_HARD* {.importc: "MM_HARD", header: "<fmtmsg.h>".}: cint +var MM_SOFT* {.importc: "MM_SOFT", header: "<fmtmsg.h>".}: cint +var MM_FIRM* {.importc: "MM_FIRM", header: "<fmtmsg.h>".}: cint +var MM_APPL* {.importc: "MM_APPL", header: "<fmtmsg.h>".}: cint +var MM_UTIL* {.importc: "MM_UTIL", header: "<fmtmsg.h>".}: cint +var MM_OPSYS* {.importc: "MM_OPSYS", header: "<fmtmsg.h>".}: cint +var MM_RECOVER* {.importc: "MM_RECOVER", header: "<fmtmsg.h>".}: cint +var MM_NRECOV* {.importc: "MM_NRECOV", header: "<fmtmsg.h>".}: cint +var MM_HALT* {.importc: "MM_HALT", header: "<fmtmsg.h>".}: cint +var MM_ERROR* {.importc: "MM_ERROR", header: "<fmtmsg.h>".}: cint +var MM_WARNING* {.importc: "MM_WARNING", header: "<fmtmsg.h>".}: cint +var MM_INFO* {.importc: "MM_INFO", header: "<fmtmsg.h>".}: cint +var MM_NOSEV* {.importc: "MM_NOSEV", header: "<fmtmsg.h>".}: cint +var MM_PRINT* {.importc: "MM_PRINT", header: "<fmtmsg.h>".}: cint +var MM_CONSOLE* {.importc: "MM_CONSOLE", header: "<fmtmsg.h>".}: cint +var MM_OK* {.importc: "MM_OK", header: "<fmtmsg.h>".}: cint +var MM_NOTOK* {.importc: "MM_NOTOK", header: "<fmtmsg.h>".}: cint +var MM_NOMSG* {.importc: "MM_NOMSG", header: "<fmtmsg.h>".}: cint +var MM_NOCON* {.importc: "MM_NOCON", header: "<fmtmsg.h>".}: cint + +# <fnmatch.h> +var FNM_NOMATCH* {.importc: "FNM_NOMATCH", header: "<fnmatch.h>".}: cint +var FNM_PATHNAME* {.importc: "FNM_PATHNAME", header: "<fnmatch.h>".}: cint +var FNM_PERIOD* {.importc: "FNM_PERIOD", header: "<fnmatch.h>".}: cint +var FNM_NOESCAPE* {.importc: "FNM_NOESCAPE", header: "<fnmatch.h>".}: cint +var FNM_NOSYS* {.importc: "FNM_NOSYS", header: "<fnmatch.h>".}: cint + +# <ftw.h> +var FTW_F* {.importc: "FTW_F", header: "<ftw.h>".}: cint +var FTW_D* {.importc: "FTW_D", header: "<ftw.h>".}: cint +var FTW_DNR* {.importc: "FTW_DNR", header: "<ftw.h>".}: cint +var FTW_DP* {.importc: "FTW_DP", header: "<ftw.h>".}: cint +var FTW_NS* {.importc: "FTW_NS", header: "<ftw.h>".}: cint +var FTW_SL* {.importc: "FTW_SL", header: "<ftw.h>".}: cint +var FTW_SLN* {.importc: "FTW_SLN", header: "<ftw.h>".}: cint +var FTW_PHYS* {.importc: "FTW_PHYS", header: "<ftw.h>".}: cint +var FTW_MOUNT* {.importc: "FTW_MOUNT", header: "<ftw.h>".}: cint +var FTW_DEPTH* {.importc: "FTW_DEPTH", header: "<ftw.h>".}: cint +var FTW_CHDIR* {.importc: "FTW_CHDIR", header: "<ftw.h>".}: cint + +# <glob.h> +var GLOB_APPEND* {.importc: "GLOB_APPEND", header: "<glob.h>".}: cint +var GLOB_DOOFFS* {.importc: "GLOB_DOOFFS", header: "<glob.h>".}: cint +var GLOB_ERR* {.importc: "GLOB_ERR", header: "<glob.h>".}: cint +var GLOB_MARK* {.importc: "GLOB_MARK", header: "<glob.h>".}: cint +var GLOB_NOCHECK* {.importc: "GLOB_NOCHECK", header: "<glob.h>".}: cint +var GLOB_NOESCAPE* {.importc: "GLOB_NOESCAPE", header: "<glob.h>".}: cint +var GLOB_NOSORT* {.importc: "GLOB_NOSORT", header: "<glob.h>".}: cint +var GLOB_ABORTED* {.importc: "GLOB_ABORTED", header: "<glob.h>".}: cint +var GLOB_NOMATCH* {.importc: "GLOB_NOMATCH", header: "<glob.h>".}: cint +var GLOB_NOSPACE* {.importc: "GLOB_NOSPACE", header: "<glob.h>".}: cint +var GLOB_NOSYS* {.importc: "GLOB_NOSYS", header: "<glob.h>".}: cint + +# <langinfo.h> +var CODESET* {.importc: "CODESET", header: "<langinfo.h>".}: cint +var D_T_FMT* {.importc: "D_T_FMT", header: "<langinfo.h>".}: cint +var D_FMT* {.importc: "D_FMT", header: "<langinfo.h>".}: cint +var T_FMT* {.importc: "T_FMT", header: "<langinfo.h>".}: cint +var T_FMT_AMPM* {.importc: "T_FMT_AMPM", header: "<langinfo.h>".}: cint +var AM_STR* {.importc: "AM_STR", header: "<langinfo.h>".}: cint +var PM_STR* {.importc: "PM_STR", header: "<langinfo.h>".}: cint +var DAY_1* {.importc: "DAY_1", header: "<langinfo.h>".}: cint +var DAY_2* {.importc: "DAY_2", header: "<langinfo.h>".}: cint +var DAY_3* {.importc: "DAY_3", header: "<langinfo.h>".}: cint +var DAY_4* {.importc: "DAY_4", header: "<langinfo.h>".}: cint +var DAY_5* {.importc: "DAY_5", header: "<langinfo.h>".}: cint +var DAY_6* {.importc: "DAY_6", header: "<langinfo.h>".}: cint +var DAY_7* {.importc: "DAY_7", header: "<langinfo.h>".}: cint +var ABDAY_1* {.importc: "ABDAY_1", header: "<langinfo.h>".}: cint +var ABDAY_2* {.importc: "ABDAY_2", header: "<langinfo.h>".}: cint +var ABDAY_3* {.importc: "ABDAY_3", header: "<langinfo.h>".}: cint +var ABDAY_4* {.importc: "ABDAY_4", header: "<langinfo.h>".}: cint +var ABDAY_5* {.importc: "ABDAY_5", header: "<langinfo.h>".}: cint +var ABDAY_6* {.importc: "ABDAY_6", header: "<langinfo.h>".}: cint +var ABDAY_7* {.importc: "ABDAY_7", header: "<langinfo.h>".}: cint +var MON_1* {.importc: "MON_1", header: "<langinfo.h>".}: cint +var MON_2* {.importc: "MON_2", header: "<langinfo.h>".}: cint +var MON_3* {.importc: "MON_3", header: "<langinfo.h>".}: cint +var MON_4* {.importc: "MON_4", header: "<langinfo.h>".}: cint +var MON_5* {.importc: "MON_5", header: "<langinfo.h>".}: cint +var MON_6* {.importc: "MON_6", header: "<langinfo.h>".}: cint +var MON_7* {.importc: "MON_7", header: "<langinfo.h>".}: cint +var MON_8* {.importc: "MON_8", header: "<langinfo.h>".}: cint +var MON_9* {.importc: "MON_9", header: "<langinfo.h>".}: cint +var MON_10* {.importc: "MON_10", header: "<langinfo.h>".}: cint +var MON_11* {.importc: "MON_11", header: "<langinfo.h>".}: cint +var MON_12* {.importc: "MON_12", header: "<langinfo.h>".}: cint +var ABMON_1* {.importc: "ABMON_1", header: "<langinfo.h>".}: cint +var ABMON_2* {.importc: "ABMON_2", header: "<langinfo.h>".}: cint +var ABMON_3* {.importc: "ABMON_3", header: "<langinfo.h>".}: cint +var ABMON_4* {.importc: "ABMON_4", header: "<langinfo.h>".}: cint +var ABMON_5* {.importc: "ABMON_5", header: "<langinfo.h>".}: cint +var ABMON_6* {.importc: "ABMON_6", header: "<langinfo.h>".}: cint +var ABMON_7* {.importc: "ABMON_7", header: "<langinfo.h>".}: cint +var ABMON_8* {.importc: "ABMON_8", header: "<langinfo.h>".}: cint +var ABMON_9* {.importc: "ABMON_9", header: "<langinfo.h>".}: cint +var ABMON_10* {.importc: "ABMON_10", header: "<langinfo.h>".}: cint +var ABMON_11* {.importc: "ABMON_11", header: "<langinfo.h>".}: cint +var ABMON_12* {.importc: "ABMON_12", header: "<langinfo.h>".}: cint +var ERA* {.importc: "ERA", header: "<langinfo.h>".}: cint +var ERA_D_FMT* {.importc: "ERA_D_FMT", header: "<langinfo.h>".}: cint +var ERA_D_T_FMT* {.importc: "ERA_D_T_FMT", header: "<langinfo.h>".}: cint +var ERA_T_FMT* {.importc: "ERA_T_FMT", header: "<langinfo.h>".}: cint +var ALT_DIGITS* {.importc: "ALT_DIGITS", header: "<langinfo.h>".}: cint +var RADIXCHAR* {.importc: "RADIXCHAR", header: "<langinfo.h>".}: cint +var THOUSEP* {.importc: "THOUSEP", header: "<langinfo.h>".}: cint +var YESEXPR* {.importc: "YESEXPR", header: "<langinfo.h>".}: cint +var NOEXPR* {.importc: "NOEXPR", header: "<langinfo.h>".}: cint +var CRNCYSTR* {.importc: "CRNCYSTR", header: "<langinfo.h>".}: cint + +# <locale.h> +var LC_ALL* {.importc: "LC_ALL", header: "<locale.h>".}: cint +var LC_COLLATE* {.importc: "LC_COLLATE", header: "<locale.h>".}: cint +var LC_CTYPE* {.importc: "LC_CTYPE", header: "<locale.h>".}: cint +var LC_MESSAGES* {.importc: "LC_MESSAGES", header: "<locale.h>".}: cint +var LC_MONETARY* {.importc: "LC_MONETARY", header: "<locale.h>".}: cint +var LC_NUMERIC* {.importc: "LC_NUMERIC", header: "<locale.h>".}: cint +var LC_TIME* {.importc: "LC_TIME", header: "<locale.h>".}: cint + +# <netdb.h> +var IPPORT_RESERVED* {.importc: "IPPORT_RESERVED", header: "<netdb.h>".}: cint +var HOST_NOT_FOUND* {.importc: "HOST_NOT_FOUND", header: "<netdb.h>".}: cint +var NO_DATA* {.importc: "NO_DATA", header: "<netdb.h>".}: cint +var NO_RECOVERY* {.importc: "NO_RECOVERY", header: "<netdb.h>".}: cint +var TRY_AGAIN* {.importc: "TRY_AGAIN", header: "<netdb.h>".}: cint +var AI_PASSIVE* {.importc: "AI_PASSIVE", header: "<netdb.h>".}: cint +var AI_CANONNAME* {.importc: "AI_CANONNAME", header: "<netdb.h>".}: cint +var AI_NUMERICHOST* {.importc: "AI_NUMERICHOST", header: "<netdb.h>".}: cint +var AI_NUMERICSERV* {.importc: "AI_NUMERICSERV", header: "<netdb.h>".}: cint +var AI_V4MAPPED* {.importc: "AI_V4MAPPED", header: "<netdb.h>".}: cint +var AI_ALL* {.importc: "AI_ALL", header: "<netdb.h>".}: cint +var AI_ADDRCONFIG* {.importc: "AI_ADDRCONFIG", header: "<netdb.h>".}: cint +var NI_NOFQDN* {.importc: "NI_NOFQDN", header: "<netdb.h>".}: cint +var NI_NUMERICHOST* {.importc: "NI_NUMERICHOST", header: "<netdb.h>".}: cint +var NI_NAMEREQD* {.importc: "NI_NAMEREQD", header: "<netdb.h>".}: cint +var NI_NUMERICSERV* {.importc: "NI_NUMERICSERV", header: "<netdb.h>".}: cint +var NI_NUMERICSCOPE* {.importc: "NI_NUMERICSCOPE", header: "<netdb.h>".}: cint +var NI_DGRAM* {.importc: "NI_DGRAM", header: "<netdb.h>".}: cint +var EAI_AGAIN* {.importc: "EAI_AGAIN", header: "<netdb.h>".}: cint +var EAI_BADFLAGS* {.importc: "EAI_BADFLAGS", header: "<netdb.h>".}: cint +var EAI_FAIL* {.importc: "EAI_FAIL", header: "<netdb.h>".}: cint +var EAI_FAMILY* {.importc: "EAI_FAMILY", header: "<netdb.h>".}: cint +var EAI_MEMORY* {.importc: "EAI_MEMORY", header: "<netdb.h>".}: cint +var EAI_NONAME* {.importc: "EAI_NONAME", header: "<netdb.h>".}: cint +var EAI_SERVICE* {.importc: "EAI_SERVICE", header: "<netdb.h>".}: cint +var EAI_SOCKTYPE* {.importc: "EAI_SOCKTYPE", header: "<netdb.h>".}: cint +var EAI_SYSTEM* {.importc: "EAI_SYSTEM", header: "<netdb.h>".}: cint +var EAI_OVERFLOW* {.importc: "EAI_OVERFLOW", header: "<netdb.h>".}: cint + +# <net/if.h> +var IF_NAMESIZE* {.importc: "IF_NAMESIZE", header: "<net/if.h>".}: cint + +# <netinet/in.h> +var IPPROTO_IP* {.importc: "IPPROTO_IP", header: "<netinet/in.h>".}: cint +var IPPROTO_IPV6* {.importc: "IPPROTO_IPV6", header: "<netinet/in.h>".}: cint +var IPPROTO_ICMP* {.importc: "IPPROTO_ICMP", header: "<netinet/in.h>".}: cint +var IPPROTO_RAW* {.importc: "IPPROTO_RAW", header: "<netinet/in.h>".}: cint +var IPPROTO_TCP* {.importc: "IPPROTO_TCP", header: "<netinet/in.h>".}: cint +var IPPROTO_UDP* {.importc: "IPPROTO_UDP", header: "<netinet/in.h>".}: cint +var INADDR_ANY* {.importc: "INADDR_ANY", header: "<netinet/in.h>".}: InAddrScalar +var INADDR_LOOPBACK* {.importc: "INADDR_LOOPBACK", header: "<netinet/in.h>".}: InAddrScalar +var INADDR_BROADCAST* {.importc: "INADDR_BROADCAST", header: "<netinet/in.h>".}: InAddrScalar +var INET_ADDRSTRLEN* {.importc: "INET_ADDRSTRLEN", header: "<netinet/in.h>".}: cint +var INET6_ADDRSTRLEN* {.importc: "INET6_ADDRSTRLEN", header: "<netinet/in.h>".}: cint +var IPV6_JOIN_GROUP* {.importc: "IPV6_JOIN_GROUP", header: "<netinet/in.h>".}: cint +var IPV6_LEAVE_GROUP* {.importc: "IPV6_LEAVE_GROUP", header: "<netinet/in.h>".}: cint +var IPV6_MULTICAST_HOPS* {.importc: "IPV6_MULTICAST_HOPS", header: "<netinet/in.h>".}: cint +var IPV6_MULTICAST_IF* {.importc: "IPV6_MULTICAST_IF", header: "<netinet/in.h>".}: cint +var IPV6_MULTICAST_LOOP* {.importc: "IPV6_MULTICAST_LOOP", header: "<netinet/in.h>".}: cint +var IPV6_UNICAST_HOPS* {.importc: "IPV6_UNICAST_HOPS", header: "<netinet/in.h>".}: cint +var IPV6_V6ONLY* {.importc: "IPV6_V6ONLY", header: "<netinet/in.h>".}: cint + +# <netinet/tcp.h> +var TCP_NODELAY* {.importc: "TCP_NODELAY", header: "<netinet/tcp.h>".}: cint + +# <nl_types.h> +var NL_SETD* {.importc: "NL_SETD", header: "<nl_types.h>".}: cint +var NL_CAT_LOCALE* {.importc: "NL_CAT_LOCALE", header: "<nl_types.h>".}: cint + +# <poll.h> +var POLLIN* {.importc: "POLLIN", header: "<poll.h>".}: cshort +var POLLRDNORM* {.importc: "POLLRDNORM", header: "<poll.h>".}: cshort +var POLLRDBAND* {.importc: "POLLRDBAND", header: "<poll.h>".}: cshort +var POLLPRI* {.importc: "POLLPRI", header: "<poll.h>".}: cshort +var POLLOUT* {.importc: "POLLOUT", header: "<poll.h>".}: cshort +var POLLWRNORM* {.importc: "POLLWRNORM", header: "<poll.h>".}: cshort +var POLLWRBAND* {.importc: "POLLWRBAND", header: "<poll.h>".}: cshort +var POLLERR* {.importc: "POLLERR", header: "<poll.h>".}: cshort +var POLLHUP* {.importc: "POLLHUP", header: "<poll.h>".}: cshort +var POLLNVAL* {.importc: "POLLNVAL", header: "<poll.h>".}: cshort + +# <pthread.h> +var PTHREAD_BARRIER_SERIAL_THREAD* {.importc: "PTHREAD_BARRIER_SERIAL_THREAD", header: "<pthread.h>".}: cint +var PTHREAD_CANCEL_ASYNCHRONOUS* {.importc: "PTHREAD_CANCEL_ASYNCHRONOUS", header: "<pthread.h>".}: cint +var PTHREAD_CANCEL_ENABLE* {.importc: "PTHREAD_CANCEL_ENABLE", header: "<pthread.h>".}: cint +var PTHREAD_CANCEL_DEFERRED* {.importc: "PTHREAD_CANCEL_DEFERRED", header: "<pthread.h>".}: cint +var PTHREAD_CANCEL_DISABLE* {.importc: "PTHREAD_CANCEL_DISABLE", header: "<pthread.h>".}: cint +var PTHREAD_CREATE_DETACHED* {.importc: "PTHREAD_CREATE_DETACHED", header: "<pthread.h>".}: cint +var PTHREAD_CREATE_JOINABLE* {.importc: "PTHREAD_CREATE_JOINABLE", header: "<pthread.h>".}: cint +var PTHREAD_EXPLICIT_SCHED* {.importc: "PTHREAD_EXPLICIT_SCHED", header: "<pthread.h>".}: cint +var PTHREAD_INHERIT_SCHED* {.importc: "PTHREAD_INHERIT_SCHED", header: "<pthread.h>".}: cint +var PTHREAD_MUTEX_DEFAULT* {.importc: "PTHREAD_MUTEX_DEFAULT", header: "<pthread.h>".}: cint +var PTHREAD_MUTEX_ERRORCHECK* {.importc: "PTHREAD_MUTEX_ERRORCHECK", header: "<pthread.h>".}: cint +var PTHREAD_MUTEX_NORMAL* {.importc: "PTHREAD_MUTEX_NORMAL", header: "<pthread.h>".}: cint +var PTHREAD_MUTEX_RECURSIVE* {.importc: "PTHREAD_MUTEX_RECURSIVE", header: "<pthread.h>".}: cint +var PTHREAD_PRIO_INHERIT* {.importc: "PTHREAD_PRIO_INHERIT", header: "<pthread.h>".}: cint +var PTHREAD_PRIO_NONE* {.importc: "PTHREAD_PRIO_NONE", header: "<pthread.h>".}: cint +var PTHREAD_PRIO_PROTECT* {.importc: "PTHREAD_PRIO_PROTECT", header: "<pthread.h>".}: cint +var PTHREAD_PROCESS_SHARED* {.importc: "PTHREAD_PROCESS_SHARED", header: "<pthread.h>".}: cint +var PTHREAD_PROCESS_PRIVATE* {.importc: "PTHREAD_PROCESS_PRIVATE", header: "<pthread.h>".}: cint +var PTHREAD_SCOPE_PROCESS* {.importc: "PTHREAD_SCOPE_PROCESS", header: "<pthread.h>".}: cint +var PTHREAD_SCOPE_SYSTEM* {.importc: "PTHREAD_SCOPE_SYSTEM", header: "<pthread.h>".}: cint + +# <sched.h> +var SCHED_FIFO* {.importc: "SCHED_FIFO", header: "<sched.h>".}: cint +var SCHED_RR* {.importc: "SCHED_RR", header: "<sched.h>".}: cint +var SCHED_SPORADIC* {.importc: "SCHED_SPORADIC", header: "<sched.h>".}: cint +var SCHED_OTHER* {.importc: "SCHED_OTHER", header: "<sched.h>".}: cint + +# <semaphore.h> +var SEM_FAILED* {.importc: "SEM_FAILED", header: "<semaphore.h>".}: pointer + +# <signal.h> +var SIGEV_NONE* {.importc: "SIGEV_NONE", header: "<signal.h>".}: cint +var SIGEV_SIGNAL* {.importc: "SIGEV_SIGNAL", header: "<signal.h>".}: cint +var SIGEV_THREAD* {.importc: "SIGEV_THREAD", header: "<signal.h>".}: cint +var SIGABRT* {.importc: "SIGABRT", header: "<signal.h>".}: cint +var SIGALRM* {.importc: "SIGALRM", header: "<signal.h>".}: cint +var SIGBUS* {.importc: "SIGBUS", header: "<signal.h>".}: cint +var SIGCHLD* {.importc: "SIGCHLD", header: "<signal.h>".}: cint +var SIGCONT* {.importc: "SIGCONT", header: "<signal.h>".}: cint +var SIGFPE* {.importc: "SIGFPE", header: "<signal.h>".}: cint +var SIGHUP* {.importc: "SIGHUP", header: "<signal.h>".}: cint +var SIGILL* {.importc: "SIGILL", header: "<signal.h>".}: cint +var SIGINT* {.importc: "SIGINT", header: "<signal.h>".}: cint +var SIGKILL* {.importc: "SIGKILL", header: "<signal.h>".}: cint +var SIGPIPE* {.importc: "SIGPIPE", header: "<signal.h>".}: cint +var SIGQUIT* {.importc: "SIGQUIT", header: "<signal.h>".}: cint +var SIGSEGV* {.importc: "SIGSEGV", header: "<signal.h>".}: cint +var SIGSTOP* {.importc: "SIGSTOP", header: "<signal.h>".}: cint +var SIGTERM* {.importc: "SIGTERM", header: "<signal.h>".}: cint +var SIGTSTP* {.importc: "SIGTSTP", header: "<signal.h>".}: cint +var SIGTTIN* {.importc: "SIGTTIN", header: "<signal.h>".}: cint +var SIGTTOU* {.importc: "SIGTTOU", header: "<signal.h>".}: cint +var SIGUSR1* {.importc: "SIGUSR1", header: "<signal.h>".}: cint +var SIGUSR2* {.importc: "SIGUSR2", header: "<signal.h>".}: cint +var SIGPOLL* {.importc: "SIGPOLL", header: "<signal.h>".}: cint +var SIGPROF* {.importc: "SIGPROF", header: "<signal.h>".}: cint +var SIGSYS* {.importc: "SIGSYS", header: "<signal.h>".}: cint +var SIGTRAP* {.importc: "SIGTRAP", header: "<signal.h>".}: cint +var SIGURG* {.importc: "SIGURG", header: "<signal.h>".}: cint +var SIGVTALRM* {.importc: "SIGVTALRM", header: "<signal.h>".}: cint +var SIGXCPU* {.importc: "SIGXCPU", header: "<signal.h>".}: cint +var SIGXFSZ* {.importc: "SIGXFSZ", header: "<signal.h>".}: cint +var SA_NOCLDSTOP* {.importc: "SA_NOCLDSTOP", header: "<signal.h>".}: cint +var SIG_BLOCK* {.importc: "SIG_BLOCK", header: "<signal.h>".}: cint +var SIG_UNBLOCK* {.importc: "SIG_UNBLOCK", header: "<signal.h>".}: cint +var SIG_SETMASK* {.importc: "SIG_SETMASK", header: "<signal.h>".}: cint +var SA_ONSTACK* {.importc: "SA_ONSTACK", header: "<signal.h>".}: cint +var SA_RESETHAND* {.importc: "SA_RESETHAND", header: "<signal.h>".}: cint +var SA_RESTART* {.importc: "SA_RESTART", header: "<signal.h>".}: cint +var SA_SIGINFO* {.importc: "SA_SIGINFO", header: "<signal.h>".}: cint +var SA_NOCLDWAIT* {.importc: "SA_NOCLDWAIT", header: "<signal.h>".}: cint +var SA_NODEFER* {.importc: "SA_NODEFER", header: "<signal.h>".}: cint +var SS_ONSTACK* {.importc: "SS_ONSTACK", header: "<signal.h>".}: cint +var SS_DISABLE* {.importc: "SS_DISABLE", header: "<signal.h>".}: cint +var MINSIGSTKSZ* {.importc: "MINSIGSTKSZ", header: "<signal.h>".}: cint +var SIGSTKSZ* {.importc: "SIGSTKSZ", header: "<signal.h>".}: cint + +# <sys/ipc.h> +var IPC_CREAT* {.importc: "IPC_CREAT", header: "<sys/ipc.h>".}: cint +var IPC_EXCL* {.importc: "IPC_EXCL", header: "<sys/ipc.h>".}: cint +var IPC_NOWAIT* {.importc: "IPC_NOWAIT", header: "<sys/ipc.h>".}: cint +var IPC_PRIVATE* {.importc: "IPC_PRIVATE", header: "<sys/ipc.h>".}: cint +var IPC_RMID* {.importc: "IPC_RMID", header: "<sys/ipc.h>".}: cint +var IPC_SET* {.importc: "IPC_SET", header: "<sys/ipc.h>".}: cint +var IPC_STAT* {.importc: "IPC_STAT", header: "<sys/ipc.h>".}: cint + +# <sys/mman.h> +var PROT_READ* {.importc: "PROT_READ", header: "<sys/mman.h>".}: cint +var PROT_WRITE* {.importc: "PROT_WRITE", header: "<sys/mman.h>".}: cint +var PROT_EXEC* {.importc: "PROT_EXEC", header: "<sys/mman.h>".}: cint +var PROT_NONE* {.importc: "PROT_NONE", header: "<sys/mman.h>".}: cint +var MAP_SHARED* {.importc: "MAP_SHARED", header: "<sys/mman.h>".}: cint +var MAP_PRIVATE* {.importc: "MAP_PRIVATE", header: "<sys/mman.h>".}: cint +var MAP_FIXED* {.importc: "MAP_FIXED", header: "<sys/mman.h>".}: cint +var MS_ASYNC* {.importc: "MS_ASYNC", header: "<sys/mman.h>".}: cint +var MS_SYNC* {.importc: "MS_SYNC", header: "<sys/mman.h>".}: cint +var MS_INVALIDATE* {.importc: "MS_INVALIDATE", header: "<sys/mman.h>".}: cint +var MCL_CURRENT* {.importc: "MCL_CURRENT", header: "<sys/mman.h>".}: cint +var MCL_FUTURE* {.importc: "MCL_FUTURE", header: "<sys/mman.h>".}: cint +var MAP_FAILED* {.importc: "MAP_FAILED", header: "<sys/mman.h>".}: pointer +var POSIX_MADV_NORMAL* {.importc: "POSIX_MADV_NORMAL", header: "<sys/mman.h>".}: cint +var POSIX_MADV_SEQUENTIAL* {.importc: "POSIX_MADV_SEQUENTIAL", header: "<sys/mman.h>".}: cint +var POSIX_MADV_RANDOM* {.importc: "POSIX_MADV_RANDOM", header: "<sys/mman.h>".}: cint +var POSIX_MADV_WILLNEED* {.importc: "POSIX_MADV_WILLNEED", header: "<sys/mman.h>".}: cint +var POSIX_MADV_DONTNEED* {.importc: "POSIX_MADV_DONTNEED", header: "<sys/mman.h>".}: cint +var POSIX_TYPED_MEM_ALLOCATE* {.importc: "POSIX_TYPED_MEM_ALLOCATE", header: "<sys/mman.h>".}: cint +var POSIX_TYPED_MEM_ALLOCATE_CONTIG* {.importc: "POSIX_TYPED_MEM_ALLOCATE_CONTIG", header: "<sys/mman.h>".}: cint +var POSIX_TYPED_MEM_MAP_ALLOCATABLE* {.importc: "POSIX_TYPED_MEM_MAP_ALLOCATABLE", header: "<sys/mman.h>".}: cint + +# <sys/select.h> +var FD_SETSIZE* {.importc: "FD_SETSIZE", header: "<sys/select.h>".}: cint + +# <sys/socket.h> +var MSG_CTRUNC* {.importc: "MSG_CTRUNC", header: "<sys/socket.h>".}: cint +var MSG_DONTROUTE* {.importc: "MSG_DONTROUTE", header: "<sys/socket.h>".}: cint +var MSG_EOR* {.importc: "MSG_EOR", header: "<sys/socket.h>".}: cint +var MSG_OOB* {.importc: "MSG_OOB", header: "<sys/socket.h>".}: cint +var SCM_RIGHTS* {.importc: "SCM_RIGHTS", header: "<sys/socket.h>".}: cint +var SO_ACCEPTCONN* {.importc: "SO_ACCEPTCONN", header: "<sys/socket.h>".}: cint +var SO_BROADCAST* {.importc: "SO_BROADCAST", header: "<sys/socket.h>".}: cint +var SO_DEBUG* {.importc: "SO_DEBUG", header: "<sys/socket.h>".}: cint +var SO_DONTROUTE* {.importc: "SO_DONTROUTE", header: "<sys/socket.h>".}: cint +var SO_ERROR* {.importc: "SO_ERROR", header: "<sys/socket.h>".}: cint +var SO_KEEPALIVE* {.importc: "SO_KEEPALIVE", header: "<sys/socket.h>".}: cint +var SO_LINGER* {.importc: "SO_LINGER", header: "<sys/socket.h>".}: cint +var SO_OOBINLINE* {.importc: "SO_OOBINLINE", header: "<sys/socket.h>".}: cint +var SO_RCVBUF* {.importc: "SO_RCVBUF", header: "<sys/socket.h>".}: cint +var SO_RCVLOWAT* {.importc: "SO_RCVLOWAT", header: "<sys/socket.h>".}: cint +var SO_RCVTIMEO* {.importc: "SO_RCVTIMEO", header: "<sys/socket.h>".}: cint +var SO_REUSEADDR* {.importc: "SO_REUSEADDR", header: "<sys/socket.h>".}: cint +var SO_SNDBUF* {.importc: "SO_SNDBUF", header: "<sys/socket.h>".}: cint +var SO_SNDLOWAT* {.importc: "SO_SNDLOWAT", header: "<sys/socket.h>".}: cint +var SO_SNDTIMEO* {.importc: "SO_SNDTIMEO", header: "<sys/socket.h>".}: cint +var SO_TYPE* {.importc: "SO_TYPE", header: "<sys/socket.h>".}: cint +var SOCK_DGRAM* {.importc: "SOCK_DGRAM", header: "<sys/socket.h>".}: cint +var SOCK_RAW* {.importc: "SOCK_RAW", header: "<sys/socket.h>".}: cint +var SOCK_SEQPACKET* {.importc: "SOCK_SEQPACKET", header: "<sys/socket.h>".}: cint +var SOCK_STREAM* {.importc: "SOCK_STREAM", header: "<sys/socket.h>".}: cint +var SOL_SOCKET* {.importc: "SOL_SOCKET", header: "<sys/socket.h>".}: cint +var SOMAXCONN* {.importc: "SOMAXCONN", header: "<sys/socket.h>".}: cint +var MSG_PEEK* {.importc: "MSG_PEEK", header: "<sys/socket.h>".}: cint +var MSG_TRUNC* {.importc: "MSG_TRUNC", header: "<sys/socket.h>".}: cint +var MSG_WAITALL* {.importc: "MSG_WAITALL", header: "<sys/socket.h>".}: cint +var AF_INET* {.importc: "AF_INET", header: "<sys/socket.h>".}: TSa_Family +var AF_INET6* {.importc: "AF_INET6", header: "<sys/socket.h>".}: TSa_Family +var AF_UNIX* {.importc: "AF_UNIX", header: "<sys/socket.h>".}: TSa_Family +var AF_UNSPEC* {.importc: "AF_UNSPEC", header: "<sys/socket.h>".}: TSa_Family +var SHUT_RD* {.importc: "SHUT_RD", header: "<sys/socket.h>".}: cint +var SHUT_RDWR* {.importc: "SHUT_RDWR", header: "<sys/socket.h>".}: cint +var SHUT_WR* {.importc: "SHUT_WR", header: "<sys/socket.h>".}: cint + +# <sys/stat.h> +var S_IFBLK* {.importc: "S_IFBLK", header: "<sys/stat.h>".}: cint +var S_IFCHR* {.importc: "S_IFCHR", header: "<sys/stat.h>".}: cint +var S_IFDIR* {.importc: "S_IFDIR", header: "<sys/stat.h>".}: cint +var S_IFIFO* {.importc: "S_IFIFO", header: "<sys/stat.h>".}: cint +var S_IFLNK* {.importc: "S_IFLNK", header: "<sys/stat.h>".}: cint +var S_IFMT* {.importc: "S_IFMT", header: "<sys/stat.h>".}: cint +var S_IFREG* {.importc: "S_IFREG", header: "<sys/stat.h>".}: cint +var S_IFSOCK* {.importc: "S_IFSOCK", header: "<sys/stat.h>".}: cint +var S_IRGRP* {.importc: "S_IRGRP", header: "<sys/stat.h>".}: cint +var S_IROTH* {.importc: "S_IROTH", header: "<sys/stat.h>".}: cint +var S_IRUSR* {.importc: "S_IRUSR", header: "<sys/stat.h>".}: cint +var S_IRWXG* {.importc: "S_IRWXG", header: "<sys/stat.h>".}: cint +var S_IRWXO* {.importc: "S_IRWXO", header: "<sys/stat.h>".}: cint +var S_IRWXU* {.importc: "S_IRWXU", header: "<sys/stat.h>".}: cint +var S_ISGID* {.importc: "S_ISGID", header: "<sys/stat.h>".}: cint +var S_ISUID* {.importc: "S_ISUID", header: "<sys/stat.h>".}: cint +var S_ISVTX* {.importc: "S_ISVTX", header: "<sys/stat.h>".}: cint +var S_IWGRP* {.importc: "S_IWGRP", header: "<sys/stat.h>".}: cint +var S_IWOTH* {.importc: "S_IWOTH", header: "<sys/stat.h>".}: cint +var S_IWUSR* {.importc: "S_IWUSR", header: "<sys/stat.h>".}: cint +var S_IXGRP* {.importc: "S_IXGRP", header: "<sys/stat.h>".}: cint +var S_IXOTH* {.importc: "S_IXOTH", header: "<sys/stat.h>".}: cint +var S_IXUSR* {.importc: "S_IXUSR", header: "<sys/stat.h>".}: cint + +# <sys/statvfs.h> +var ST_RDONLY* {.importc: "ST_RDONLY", header: "<sys/statvfs.h>".}: cint +var ST_NOSUID* {.importc: "ST_NOSUID", header: "<sys/statvfs.h>".}: cint + +# <sys/wait.h> +var WNOHANG* {.importc: "WNOHANG", header: "<sys/wait.h>".}: cint +var WUNTRACED* {.importc: "WUNTRACED", header: "<sys/wait.h>".}: cint +var WEXITED* {.importc: "WEXITED", header: "<sys/wait.h>".}: cint +var WSTOPPED* {.importc: "WSTOPPED", header: "<sys/wait.h>".}: cint +var WCONTINUED* {.importc: "WCONTINUED", header: "<sys/wait.h>".}: cint +var WNOWAIT* {.importc: "WNOWAIT", header: "<sys/wait.h>".}: cint +var P_ALL* {.importc: "P_ALL", header: "<sys/wait.h>".}: cint +var P_PID* {.importc: "P_PID", header: "<sys/wait.h>".}: cint +var P_PGID* {.importc: "P_PGID", header: "<sys/wait.h>".}: cint + +# <spawn.h> +var POSIX_SPAWN_RESETIDS* {.importc: "POSIX_SPAWN_RESETIDS", header: "<spawn.h>".}: cint +var POSIX_SPAWN_SETPGROUP* {.importc: "POSIX_SPAWN_SETPGROUP", header: "<spawn.h>".}: cint +var POSIX_SPAWN_SETSCHEDPARAM* {.importc: "POSIX_SPAWN_SETSCHEDPARAM", header: "<spawn.h>".}: cint +var POSIX_SPAWN_SETSCHEDULER* {.importc: "POSIX_SPAWN_SETSCHEDULER", header: "<spawn.h>".}: cint +var POSIX_SPAWN_SETSIGDEF* {.importc: "POSIX_SPAWN_SETSIGDEF", header: "<spawn.h>".}: cint +var POSIX_SPAWN_SETSIGMASK* {.importc: "POSIX_SPAWN_SETSIGMASK", header: "<spawn.h>".}: cint + +# <stdio.h> +var IOFBF* {.importc: "_IOFBF", header: "<stdio.h>".}: cint +var IONBF* {.importc: "_IONBF", header: "<stdio.h>".}: cint + +# <time.h> +var CLOCKS_PER_SEC* {.importc: "CLOCKS_PER_SEC", header: "<time.h>".}: clong +var CLOCK_PROCESS_CPUTIME_ID* {.importc: "CLOCK_PROCESS_CPUTIME_ID", header: "<time.h>".}: cint +var CLOCK_THREAD_CPUTIME_ID* {.importc: "CLOCK_THREAD_CPUTIME_ID", header: "<time.h>".}: cint +var CLOCK_REALTIME* {.importc: "CLOCK_REALTIME", header: "<time.h>".}: cint +var TIMER_ABSTIME* {.importc: "TIMER_ABSTIME", header: "<time.h>".}: cint +var CLOCK_MONOTONIC* {.importc: "CLOCK_MONOTONIC", header: "<time.h>".}: cint + +# <unistd.h> +var POSIX_ASYNC_IO* {.importc: "_POSIX_ASYNC_IO", header: "<unistd.h>".}: cint +var POSIX_PRIO_IO* {.importc: "_POSIX_PRIO_IO", header: "<unistd.h>".}: cint +var POSIX_SYNC_IO* {.importc: "_POSIX_SYNC_IO", header: "<unistd.h>".}: cint +var F_OK* {.importc: "F_OK", header: "<unistd.h>".}: cint +var R_OK* {.importc: "R_OK", header: "<unistd.h>".}: cint +var W_OK* {.importc: "W_OK", header: "<unistd.h>".}: cint +var X_OK* {.importc: "X_OK", header: "<unistd.h>".}: cint +var CS_PATH* {.importc: "_CS_PATH", header: "<unistd.h>".}: cint +var CS_POSIX_V6_ILP32_OFF32_CFLAGS* {.importc: "_CS_POSIX_V6_ILP32_OFF32_CFLAGS", header: "<unistd.h>".}: cint +var CS_POSIX_V6_ILP32_OFF32_LDFLAGS* {.importc: "_CS_POSIX_V6_ILP32_OFF32_LDFLAGS", header: "<unistd.h>".}: cint +var CS_POSIX_V6_ILP32_OFF32_LIBS* {.importc: "_CS_POSIX_V6_ILP32_OFF32_LIBS", header: "<unistd.h>".}: cint +var CS_POSIX_V6_ILP32_OFFBIG_CFLAGS* {.importc: "_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS", header: "<unistd.h>".}: cint +var CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS* {.importc: "_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS", header: "<unistd.h>".}: cint +var CS_POSIX_V6_ILP32_OFFBIG_LIBS* {.importc: "_CS_POSIX_V6_ILP32_OFFBIG_LIBS", header: "<unistd.h>".}: cint +var CS_POSIX_V6_LP64_OFF64_CFLAGS* {.importc: "_CS_POSIX_V6_LP64_OFF64_CFLAGS", header: "<unistd.h>".}: cint +var CS_POSIX_V6_LP64_OFF64_LDFLAGS* {.importc: "_CS_POSIX_V6_LP64_OFF64_LDFLAGS", header: "<unistd.h>".}: cint +var CS_POSIX_V6_LP64_OFF64_LIBS* {.importc: "_CS_POSIX_V6_LP64_OFF64_LIBS", header: "<unistd.h>".}: cint +var CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS* {.importc: "_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS", header: "<unistd.h>".}: cint +var CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS* {.importc: "_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS", header: "<unistd.h>".}: cint +var CS_POSIX_V6_LPBIG_OFFBIG_LIBS* {.importc: "_CS_POSIX_V6_LPBIG_OFFBIG_LIBS", header: "<unistd.h>".}: cint +var CS_POSIX_V6_WIDTH_RESTRICTED_ENVS* {.importc: "_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS", header: "<unistd.h>".}: cint +var F_LOCK* {.importc: "F_LOCK", header: "<unistd.h>".}: cint +var F_TEST* {.importc: "F_TEST", header: "<unistd.h>".}: cint +var F_TLOCK* {.importc: "F_TLOCK", header: "<unistd.h>".}: cint +var F_ULOCK* {.importc: "F_ULOCK", header: "<unistd.h>".}: cint +var PC_2_SYMLINKS* {.importc: "_PC_2_SYMLINKS", header: "<unistd.h>".}: cint +var PC_ALLOC_SIZE_MIN* {.importc: "_PC_ALLOC_SIZE_MIN", header: "<unistd.h>".}: cint +var PC_ASYNC_IO* {.importc: "_PC_ASYNC_IO", header: "<unistd.h>".}: cint +var PC_CHOWN_RESTRICTED* {.importc: "_PC_CHOWN_RESTRICTED", header: "<unistd.h>".}: cint +var PC_FILESIZEBITS* {.importc: "_PC_FILESIZEBITS", header: "<unistd.h>".}: cint +var PC_LINK_MAX* {.importc: "_PC_LINK_MAX", header: "<unistd.h>".}: cint +var PC_MAX_CANON* {.importc: "_PC_MAX_CANON", header: "<unistd.h>".}: cint +var PC_MAX_INPUT* {.importc: "_PC_MAX_INPUT", header: "<unistd.h>".}: cint +var PC_NAME_MAX* {.importc: "_PC_NAME_MAX", header: "<unistd.h>".}: cint +var PC_NO_TRUNC* {.importc: "_PC_NO_TRUNC", header: "<unistd.h>".}: cint +var PC_PATH_MAX* {.importc: "_PC_PATH_MAX", header: "<unistd.h>".}: cint +var PC_PIPE_BUF* {.importc: "_PC_PIPE_BUF", header: "<unistd.h>".}: cint +var PC_PRIO_IO* {.importc: "_PC_PRIO_IO", header: "<unistd.h>".}: cint +var PC_REC_INCR_XFER_SIZE* {.importc: "_PC_REC_INCR_XFER_SIZE", header: "<unistd.h>".}: cint +var PC_REC_MIN_XFER_SIZE* {.importc: "_PC_REC_MIN_XFER_SIZE", header: "<unistd.h>".}: cint +var PC_REC_XFER_ALIGN* {.importc: "_PC_REC_XFER_ALIGN", header: "<unistd.h>".}: cint +var PC_SYMLINK_MAX* {.importc: "_PC_SYMLINK_MAX", header: "<unistd.h>".}: cint +var PC_SYNC_IO* {.importc: "_PC_SYNC_IO", header: "<unistd.h>".}: cint +var PC_VDISABLE* {.importc: "_PC_VDISABLE", header: "<unistd.h>".}: cint +var SC_2_C_BIND* {.importc: "_SC_2_C_BIND", header: "<unistd.h>".}: cint +var SC_2_C_DEV* {.importc: "_SC_2_C_DEV", header: "<unistd.h>".}: cint +var SC_2_CHAR_TERM* {.importc: "_SC_2_CHAR_TERM", header: "<unistd.h>".}: cint +var SC_2_FORT_DEV* {.importc: "_SC_2_FORT_DEV", header: "<unistd.h>".}: cint +var SC_2_FORT_RUN* {.importc: "_SC_2_FORT_RUN", header: "<unistd.h>".}: cint +var SC_2_LOCALEDEF* {.importc: "_SC_2_LOCALEDEF", header: "<unistd.h>".}: cint +var SC_2_PBS* {.importc: "_SC_2_PBS", header: "<unistd.h>".}: cint +var SC_2_PBS_ACCOUNTING* {.importc: "_SC_2_PBS_ACCOUNTING", header: "<unistd.h>".}: cint +var SC_2_PBS_CHECKPOINT* {.importc: "_SC_2_PBS_CHECKPOINT", header: "<unistd.h>".}: cint +var SC_2_PBS_LOCATE* {.importc: "_SC_2_PBS_LOCATE", header: "<unistd.h>".}: cint +var SC_2_PBS_MESSAGE* {.importc: "_SC_2_PBS_MESSAGE", header: "<unistd.h>".}: cint +var SC_2_PBS_TRACK* {.importc: "_SC_2_PBS_TRACK", header: "<unistd.h>".}: cint +var SC_2_SW_DEV* {.importc: "_SC_2_SW_DEV", header: "<unistd.h>".}: cint +var SC_2_UPE* {.importc: "_SC_2_UPE", header: "<unistd.h>".}: cint +var SC_2_VERSION* {.importc: "_SC_2_VERSION", header: "<unistd.h>".}: cint +var SC_ADVISORY_INFO* {.importc: "_SC_ADVISORY_INFO", header: "<unistd.h>".}: cint +var SC_AIO_LISTIO_MAX* {.importc: "_SC_AIO_LISTIO_MAX", header: "<unistd.h>".}: cint +var SC_AIO_MAX* {.importc: "_SC_AIO_MAX", header: "<unistd.h>".}: cint +var SC_AIO_PRIO_DELTA_MAX* {.importc: "_SC_AIO_PRIO_DELTA_MAX", header: "<unistd.h>".}: cint +var SC_ARG_MAX* {.importc: "_SC_ARG_MAX", header: "<unistd.h>".}: cint +var SC_ASYNCHRONOUS_IO* {.importc: "_SC_ASYNCHRONOUS_IO", header: "<unistd.h>".}: cint +var SC_ATEXIT_MAX* {.importc: "_SC_ATEXIT_MAX", header: "<unistd.h>".}: cint +var SC_BARRIERS* {.importc: "_SC_BARRIERS", header: "<unistd.h>".}: cint +var SC_BC_BASE_MAX* {.importc: "_SC_BC_BASE_MAX", header: "<unistd.h>".}: cint +var SC_BC_DIM_MAX* {.importc: "_SC_BC_DIM_MAX", header: "<unistd.h>".}: cint +var SC_BC_SCALE_MAX* {.importc: "_SC_BC_SCALE_MAX", header: "<unistd.h>".}: cint +var SC_BC_STRING_MAX* {.importc: "_SC_BC_STRING_MAX", header: "<unistd.h>".}: cint +var SC_CHILD_MAX* {.importc: "_SC_CHILD_MAX", header: "<unistd.h>".}: cint +var SC_CLK_TCK* {.importc: "_SC_CLK_TCK", header: "<unistd.h>".}: cint +var SC_CLOCK_SELECTION* {.importc: "_SC_CLOCK_SELECTION", header: "<unistd.h>".}: cint +var SC_COLL_WEIGHTS_MAX* {.importc: "_SC_COLL_WEIGHTS_MAX", header: "<unistd.h>".}: cint +var SC_CPUTIME* {.importc: "_SC_CPUTIME", header: "<unistd.h>".}: cint +var SC_DELAYTIMER_MAX* {.importc: "_SC_DELAYTIMER_MAX", header: "<unistd.h>".}: cint +var SC_EXPR_NEST_MAX* {.importc: "_SC_EXPR_NEST_MAX", header: "<unistd.h>".}: cint +var SC_FSYNC* {.importc: "_SC_FSYNC", header: "<unistd.h>".}: cint +var SC_GETGR_R_SIZE_MAX* {.importc: "_SC_GETGR_R_SIZE_MAX", header: "<unistd.h>".}: cint +var SC_GETPW_R_SIZE_MAX* {.importc: "_SC_GETPW_R_SIZE_MAX", header: "<unistd.h>".}: cint +var SC_HOST_NAME_MAX* {.importc: "_SC_HOST_NAME_MAX", header: "<unistd.h>".}: cint +var SC_IOV_MAX* {.importc: "_SC_IOV_MAX", header: "<unistd.h>".}: cint +var SC_IPV6* {.importc: "_SC_IPV6", header: "<unistd.h>".}: cint +var SC_JOB_CONTROL* {.importc: "_SC_JOB_CONTROL", header: "<unistd.h>".}: cint +var SC_LINE_MAX* {.importc: "_SC_LINE_MAX", header: "<unistd.h>".}: cint +var SC_LOGIN_NAME_MAX* {.importc: "_SC_LOGIN_NAME_MAX", header: "<unistd.h>".}: cint +var SC_MAPPED_FILES* {.importc: "_SC_MAPPED_FILES", header: "<unistd.h>".}: cint +var SC_MEMLOCK* {.importc: "_SC_MEMLOCK", header: "<unistd.h>".}: cint +var SC_MEMLOCK_RANGE* {.importc: "_SC_MEMLOCK_RANGE", header: "<unistd.h>".}: cint +var SC_MEMORY_PROTECTION* {.importc: "_SC_MEMORY_PROTECTION", header: "<unistd.h>".}: cint +var SC_MESSAGE_PASSING* {.importc: "_SC_MESSAGE_PASSING", header: "<unistd.h>".}: cint +var SC_MONOTONIC_CLOCK* {.importc: "_SC_MONOTONIC_CLOCK", header: "<unistd.h>".}: cint +var SC_MQ_OPEN_MAX* {.importc: "_SC_MQ_OPEN_MAX", header: "<unistd.h>".}: cint +var SC_MQ_PRIO_MAX* {.importc: "_SC_MQ_PRIO_MAX", header: "<unistd.h>".}: cint +var SC_NGROUPS_MAX* {.importc: "_SC_NGROUPS_MAX", header: "<unistd.h>".}: cint +var SC_OPEN_MAX* {.importc: "_SC_OPEN_MAX", header: "<unistd.h>".}: cint +var SC_PAGE_SIZE* {.importc: "_SC_PAGE_SIZE", header: "<unistd.h>".}: cint +var SC_PRIORITIZED_IO* {.importc: "_SC_PRIORITIZED_IO", header: "<unistd.h>".}: cint +var SC_PRIORITY_SCHEDULING* {.importc: "_SC_PRIORITY_SCHEDULING", header: "<unistd.h>".}: cint +var SC_RAW_SOCKETS* {.importc: "_SC_RAW_SOCKETS", header: "<unistd.h>".}: cint +var SC_RE_DUP_MAX* {.importc: "_SC_RE_DUP_MAX", header: "<unistd.h>".}: cint +var SC_READER_WRITER_LOCKS* {.importc: "_SC_READER_WRITER_LOCKS", header: "<unistd.h>".}: cint +var SC_REALTIME_SIGNALS* {.importc: "_SC_REALTIME_SIGNALS", header: "<unistd.h>".}: cint +var SC_REGEXP* {.importc: "_SC_REGEXP", header: "<unistd.h>".}: cint +var SC_RTSIG_MAX* {.importc: "_SC_RTSIG_MAX", header: "<unistd.h>".}: cint +var SC_SAVED_IDS* {.importc: "_SC_SAVED_IDS", header: "<unistd.h>".}: cint +var SC_SEM_NSEMS_MAX* {.importc: "_SC_SEM_NSEMS_MAX", header: "<unistd.h>".}: cint +var SC_SEM_VALUE_MAX* {.importc: "_SC_SEM_VALUE_MAX", header: "<unistd.h>".}: cint +var SC_SEMAPHORES* {.importc: "_SC_SEMAPHORES", header: "<unistd.h>".}: cint +var SC_SHARED_MEMORY_OBJECTS* {.importc: "_SC_SHARED_MEMORY_OBJECTS", header: "<unistd.h>".}: cint +var SC_SHELL* {.importc: "_SC_SHELL", header: "<unistd.h>".}: cint +var SC_SIGQUEUE_MAX* {.importc: "_SC_SIGQUEUE_MAX", header: "<unistd.h>".}: cint +var SC_SPAWN* {.importc: "_SC_SPAWN", header: "<unistd.h>".}: cint +var SC_SPIN_LOCKS* {.importc: "_SC_SPIN_LOCKS", header: "<unistd.h>".}: cint +var SC_SPORADIC_SERVER* {.importc: "_SC_SPORADIC_SERVER", header: "<unistd.h>".}: cint +var SC_SS_REPL_MAX* {.importc: "_SC_SS_REPL_MAX", header: "<unistd.h>".}: cint +var SC_STREAM_MAX* {.importc: "_SC_STREAM_MAX", header: "<unistd.h>".}: cint +var SC_SYMLOOP_MAX* {.importc: "_SC_SYMLOOP_MAX", header: "<unistd.h>".}: cint +var SC_SYNCHRONIZED_IO* {.importc: "_SC_SYNCHRONIZED_IO", header: "<unistd.h>".}: cint +var SC_THREAD_ATTR_STACKADDR* {.importc: "_SC_THREAD_ATTR_STACKADDR", header: "<unistd.h>".}: cint +var SC_THREAD_ATTR_STACKSIZE* {.importc: "_SC_THREAD_ATTR_STACKSIZE", header: "<unistd.h>".}: cint +var SC_THREAD_CPUTIME* {.importc: "_SC_THREAD_CPUTIME", header: "<unistd.h>".}: cint +var SC_THREAD_DESTRUCTOR_ITERATIONS* {.importc: "_SC_THREAD_DESTRUCTOR_ITERATIONS", header: "<unistd.h>".}: cint +var SC_THREAD_KEYS_MAX* {.importc: "_SC_THREAD_KEYS_MAX", header: "<unistd.h>".}: cint +var SC_THREAD_PRIO_INHERIT* {.importc: "_SC_THREAD_PRIO_INHERIT", header: "<unistd.h>".}: cint +var SC_THREAD_PRIO_PROTECT* {.importc: "_SC_THREAD_PRIO_PROTECT", header: "<unistd.h>".}: cint +var SC_THREAD_PRIORITY_SCHEDULING* {.importc: "_SC_THREAD_PRIORITY_SCHEDULING", header: "<unistd.h>".}: cint +var SC_THREAD_PROCESS_SHARED* {.importc: "_SC_THREAD_PROCESS_SHARED", header: "<unistd.h>".}: cint +var SC_THREAD_SAFE_FUNCTIONS* {.importc: "_SC_THREAD_SAFE_FUNCTIONS", header: "<unistd.h>".}: cint +var SC_THREAD_SPORADIC_SERVER* {.importc: "_SC_THREAD_SPORADIC_SERVER", header: "<unistd.h>".}: cint +var SC_THREAD_STACK_MIN* {.importc: "_SC_THREAD_STACK_MIN", header: "<unistd.h>".}: cint +var SC_THREAD_THREADS_MAX* {.importc: "_SC_THREAD_THREADS_MAX", header: "<unistd.h>".}: cint +var SC_THREADS* {.importc: "_SC_THREADS", header: "<unistd.h>".}: cint +var SC_TIMEOUTS* {.importc: "_SC_TIMEOUTS", header: "<unistd.h>".}: cint +var SC_TIMER_MAX* {.importc: "_SC_TIMER_MAX", header: "<unistd.h>".}: cint +var SC_TIMERS* {.importc: "_SC_TIMERS", header: "<unistd.h>".}: cint +var SC_TRACE* {.importc: "_SC_TRACE", header: "<unistd.h>".}: cint +var SC_TRACE_EVENT_FILTER* {.importc: "_SC_TRACE_EVENT_FILTER", header: "<unistd.h>".}: cint +var SC_TRACE_EVENT_NAME_MAX* {.importc: "_SC_TRACE_EVENT_NAME_MAX", header: "<unistd.h>".}: cint +var SC_TRACE_INHERIT* {.importc: "_SC_TRACE_INHERIT", header: "<unistd.h>".}: cint +var SC_TRACE_LOG* {.importc: "_SC_TRACE_LOG", header: "<unistd.h>".}: cint +var SC_TRACE_NAME_MAX* {.importc: "_SC_TRACE_NAME_MAX", header: "<unistd.h>".}: cint +var SC_TRACE_SYS_MAX* {.importc: "_SC_TRACE_SYS_MAX", header: "<unistd.h>".}: cint +var SC_TRACE_USER_EVENT_MAX* {.importc: "_SC_TRACE_USER_EVENT_MAX", header: "<unistd.h>".}: cint +var SC_TTY_NAME_MAX* {.importc: "_SC_TTY_NAME_MAX", header: "<unistd.h>".}: cint +var SC_TYPED_MEMORY_OBJECTS* {.importc: "_SC_TYPED_MEMORY_OBJECTS", header: "<unistd.h>".}: cint +var SC_TZNAME_MAX* {.importc: "_SC_TZNAME_MAX", header: "<unistd.h>".}: cint +var SC_V6_ILP32_OFF32* {.importc: "_SC_V6_ILP32_OFF32", header: "<unistd.h>".}: cint +var SC_V6_ILP32_OFFBIG* {.importc: "_SC_V6_ILP32_OFFBIG", header: "<unistd.h>".}: cint +var SC_V6_LP64_OFF64* {.importc: "_SC_V6_LP64_OFF64", header: "<unistd.h>".}: cint +var SC_V6_LPBIG_OFFBIG* {.importc: "_SC_V6_LPBIG_OFFBIG", header: "<unistd.h>".}: cint +var SC_VERSION* {.importc: "_SC_VERSION", header: "<unistd.h>".}: cint +var SC_XBS5_ILP32_OFF32* {.importc: "_SC_XBS5_ILP32_OFF32", header: "<unistd.h>".}: cint +var SC_XBS5_ILP32_OFFBIG* {.importc: "_SC_XBS5_ILP32_OFFBIG", header: "<unistd.h>".}: cint +var SC_XBS5_LP64_OFF64* {.importc: "_SC_XBS5_LP64_OFF64", header: "<unistd.h>".}: cint +var SC_XBS5_LPBIG_OFFBIG* {.importc: "_SC_XBS5_LPBIG_OFFBIG", header: "<unistd.h>".}: cint +var SC_XOPEN_CRYPT* {.importc: "_SC_XOPEN_CRYPT", header: "<unistd.h>".}: cint +var SC_XOPEN_ENH_I18N* {.importc: "_SC_XOPEN_ENH_I18N", header: "<unistd.h>".}: cint +var SC_XOPEN_LEGACY* {.importc: "_SC_XOPEN_LEGACY", header: "<unistd.h>".}: cint +var SC_XOPEN_REALTIME* {.importc: "_SC_XOPEN_REALTIME", header: "<unistd.h>".}: cint +var SC_XOPEN_REALTIME_THREADS* {.importc: "_SC_XOPEN_REALTIME_THREADS", header: "<unistd.h>".}: cint +var SC_XOPEN_SHM* {.importc: "_SC_XOPEN_SHM", header: "<unistd.h>".}: cint +var SC_XOPEN_STREAMS* {.importc: "_SC_XOPEN_STREAMS", header: "<unistd.h>".}: cint +var SC_XOPEN_UNIX* {.importc: "_SC_XOPEN_UNIX", header: "<unistd.h>".}: cint +var SC_XOPEN_VERSION* {.importc: "_SC_XOPEN_VERSION", header: "<unistd.h>".}: cint +var SC_NPROCESSORS_ONLN* {.importc: "_SC_NPROCESSORS_ONLN", header: "<unistd.h>".}: cint +var SEEK_SET* {.importc: "SEEK_SET", header: "<unistd.h>".}: cint +var SEEK_CUR* {.importc: "SEEK_CUR", header: "<unistd.h>".}: cint +var SEEK_END* {.importc: "SEEK_END", header: "<unistd.h>".}: cint + diff --git a/lib/posix/termios.nim b/lib/posix/termios.nim index af62bdb3d..21b21aefb 100644 --- a/lib/posix/termios.nim +++ b/lib/posix/termios.nim @@ -18,13 +18,25 @@ type const NCCS* = when defined(macosx): 20 else: 32 -type - Termios* {.importc: "struct termios", header: "<termios.h>".} = object - c_iflag*: Cflag # input mode flags - c_oflag*: Cflag # output mode flags - c_cflag*: Cflag # control mode flags - c_lflag*: Cflag # local mode flags - c_cc*: array[NCCS, cuchar] # control characters +when defined(linux) and defined(amd64): + type + Termios* {.importc: "struct termios", header: "<termios.h>".} = object + c_iflag*: Cflag # input mode flags + c_oflag*: Cflag # output mode flags + c_cflag*: Cflag # control mode flags + c_lflag*: Cflag # local mode flags + c_line*: cuchar + c_cc*: array[NCCS, cuchar] # control characters + c_ispeed*: Speed + c_ospeed*: Speed +else: + type + Termios* {.importc: "struct termios", header: "<termios.h>".} = object + c_iflag*: Cflag # input mode flags + c_oflag*: Cflag # output mode flags + c_cflag*: Cflag # control mode flags + c_lflag*: Cflag # local mode flags + c_cc*: array[NCCS, cuchar] # control characters # cc characters diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 1696c4ed9..1697384e0 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -9,7 +9,7 @@ include "system/inclrtl" -import os, oids, tables, strutils, times, heapqueue +import os, tables, strutils, times, heapqueue, options import nativesockets, net, deques @@ -242,6 +242,11 @@ when defined(windows) or defined(nimdoc): if gDisp.isNil: gDisp = newDispatcher() result = gDisp + proc setGlobalDispatcher*(disp: PDispatcher) = + if not gDisp.isNil: + assert gDisp.callbacks.len == 0 + gDisp = disp + proc register*(fd: AsyncFD) = ## Registers ``fd`` with the dispatcher. let p = getGlobalDispatcher() @@ -385,68 +390,6 @@ when defined(windows) or defined(nimdoc): dwRemoteAddressLength, LocalSockaddr, LocalSockaddrLength, RemoteSockaddr, RemoteSockaddrLength) - proc connect*(socket: AsyncFD, address: string, port: Port, - domain = nativesockets.AF_INET): Future[void] = - ## Connects ``socket`` to server at ``address:port``. - ## - ## Returns a ``Future`` which will complete when the connection succeeds - ## or an error occurs. - verifyPresence(socket) - var retFuture = newFuture[void]("connect") - # Apparently ``ConnectEx`` expects the socket to be initially bound: - var saddr: Sockaddr_in - saddr.sin_family = int16(toInt(domain)) - saddr.sin_port = 0 - saddr.sin_addr.s_addr = INADDR_ANY - if bindAddr(socket.SocketHandle, cast[ptr SockAddr](addr(saddr)), - sizeof(saddr).SockLen) < 0'i32: - raiseOSError(osLastError()) - - var aiList = getAddrInfo(address, port, domain) - var success = false - var lastError: OSErrorCode - var it = aiList - while it != nil: - # "the OVERLAPPED structure must remain valid until the I/O completes" - # http://blogs.msdn.com/b/oldnewthing/archive/2011/02/02/10123392.aspx - var ol = PCustomOverlapped() - GC_ref(ol) - ol.data = CompletionData(fd: socket, cb: - proc (fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = - if not retFuture.finished: - if errcode == OSErrorCode(-1): - retFuture.complete() - else: - retFuture.fail(newException(OSError, osErrorMsg(errcode))) - ) - - var ret = connectEx(socket.SocketHandle, it.ai_addr, - sizeof(Sockaddr_in).cint, nil, 0, nil, - cast[POVERLAPPED](ol)) - if ret: - # Request to connect completed immediately. - success = true - retFuture.complete() - # We don't deallocate ``ol`` here because even though this completed - # immediately poll will still be notified about its completion and it will - # free ``ol``. - break - else: - lastError = osLastError() - if lastError.int32 == ERROR_IO_PENDING: - # In this case ``ol`` will be deallocated in ``poll``. - success = true - break - else: - GC_unref(ol) - success = false - it = it.ai_next - - freeAddrInfo(aiList) - if not success: - retFuture.fail(newException(OSError, osErrorMsg(lastError))) - return retFuture - proc recv*(socket: AsyncFD, size: int, flags = {SocketFlag.SafeDisconn}): Future[string] = ## Reads **up to** ``size`` bytes from ``socket``. Returned future will @@ -754,8 +697,8 @@ when defined(windows) or defined(nimdoc): var lpOutputBuf = newString(lpOutputLen) var dwBytesReceived: Dword let dwReceiveDataLength = 0.Dword # We don't want any data to be read. - let dwLocalAddressLength = Dword(sizeof(Sockaddr_in) + 16) - let dwRemoteAddressLength = Dword(sizeof(Sockaddr_in) + 16) + let dwLocalAddressLength = Dword(sizeof(Sockaddr_in6) + 16) + let dwRemoteAddressLength = Dword(sizeof(Sockaddr_in6) + 16) template failAccept(errcode) = if flags.isDisconnectionError(errcode): @@ -785,12 +728,14 @@ when defined(windows) or defined(nimdoc): dwLocalAddressLength, dwRemoteAddressLength, addr localSockaddr, addr localLen, addr remoteSockaddr, addr remoteLen) - register(clientSock.AsyncFD) - # TODO: IPv6. Check ``sa_family``. http://stackoverflow.com/a/9212542/492186 - retFuture.complete( - (address: $inet_ntoa(cast[ptr Sockaddr_in](remoteSockAddr).sin_addr), - client: clientSock.AsyncFD) - ) + try: + let address = getAddrString(remoteSockAddr) + register(clientSock.AsyncFD) + retFuture.complete((address: address, client: clientSock.AsyncFD)) + except: + # getAddrString may raise + clientSock.close() + retFuture.fail(getCurrentException()) var ol = PCustomOverlapped() GC_ref(ol) @@ -823,20 +768,6 @@ when defined(windows) or defined(nimdoc): return retFuture - proc newAsyncNativeSocket*(domain, sockType, protocol: cint): AsyncFD = - ## Creates a new socket and registers it with the dispatcher implicitly. - result = newNativeSocket(domain, sockType, protocol).AsyncFD - result.SocketHandle.setBlocking(false) - register(result) - - proc newAsyncNativeSocket*(domain: Domain = nativesockets.AF_INET, - sockType: SockType = SOCK_STREAM, - protocol: Protocol = IPPROTO_TCP): AsyncFD = - ## Creates a new socket and registers it with the dispatcher implicitly. - result = newNativeSocket(domain, sockType, protocol).AsyncFD - result.SocketHandle.setBlocking(false) - register(result) - proc closeSocket*(socket: AsyncFD) = ## Closes a socket and ensures that it is unregistered. socket.SocketHandle.close() @@ -1005,6 +936,11 @@ else: if gDisp.isNil: gDisp = newDispatcher() result = gDisp + proc setGlobalDispatcher*(disp: PDispatcher) = + if not gDisp.isNil: + assert gDisp.callbacks.len == 0 + gDisp = disp + proc update(fd: AsyncFD, events: set[Event]) = let p = getGlobalDispatcher() assert fd.SocketHandle in p.selector @@ -1015,23 +951,6 @@ else: var data = PData(fd: fd, readCBs: @[], writeCBs: @[]) p.selector.register(fd.SocketHandle, {}, data.RootRef) - proc newAsyncNativeSocket*(domain: cint, sockType: cint, - protocol: cint): AsyncFD = - result = newNativeSocket(domain, sockType, protocol).AsyncFD - result.SocketHandle.setBlocking(false) - when defined(macosx): - result.SocketHandle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1) - register(result) - - proc newAsyncNativeSocket*(domain: Domain = AF_INET, - sockType: SockType = SOCK_STREAM, - protocol: Protocol = IPPROTO_TCP): AsyncFD = - result = newNativeSocket(domain, sockType, protocol).AsyncFD - result.SocketHandle.setBlocking(false) - when defined(macosx): - result.SocketHandle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1) - register(result) - proc closeSocket*(sock: AsyncFD) = let disp = getGlobalDispatcher() disp.selector.unregister(sock.SocketHandle) @@ -1115,50 +1034,6 @@ else: # Callback queue processing processPendingCallbacks(p) - proc connect*(socket: AsyncFD, address: string, port: Port, - domain = AF_INET): Future[void] = - var retFuture = newFuture[void]("connect") - - proc cb(fd: AsyncFD): bool = - var ret = SocketHandle(fd).getSockOptInt(cint(SOL_SOCKET), cint(SO_ERROR)) - if ret == 0: - # We have connected. - retFuture.complete() - return true - elif ret == EINTR: - # interrupted, keep waiting - return false - else: - retFuture.fail(newException(OSError, osErrorMsg(OSErrorCode(ret)))) - return true - - assert getSockDomain(socket.SocketHandle) == domain - var aiList = getAddrInfo(address, port, domain) - var success = false - var lastError: OSErrorCode - var it = aiList - while it != nil: - var ret = connect(socket.SocketHandle, it.ai_addr, it.ai_addrlen.Socklen) - if ret == 0: - # Request to connect completed immediately. - success = true - retFuture.complete() - break - else: - lastError = osLastError() - if lastError.int32 == EINTR or lastError.int32 == EINPROGRESS: - success = true - addWrite(socket, cb) - break - else: - success = false - it = it.ai_next - - freeAddrInfo(aiList) - if not success: - retFuture.fail(newException(OSError, osErrorMsg(lastError))) - return retFuture - proc recv*(socket: AsyncFD, size: int, flags = {SocketFlag.SafeDisconn}): Future[string] = var retFuture = newFuture[string]("recv") @@ -1320,11 +1195,20 @@ else: else: retFuture.fail(newException(OSError, osErrorMsg(lastError))) else: - register(client.AsyncFD) - retFuture.complete((getAddrString(cast[ptr SockAddr](addr sockAddress)), client.AsyncFD)) + try: + let address = getAddrString(cast[ptr SockAddr](addr sockAddress)) + register(client.AsyncFD) + retFuture.complete((address, client.AsyncFD)) + except: + # getAddrString may raise + client.close() + retFuture.fail(getCurrentException()) addRead(socket, cb) return retFuture +# Common procedures between current and upcoming asyncdispatch +include includes.asynccommon + proc sleepAsync*(ms: int): Future[void] = ## Suspends the execution of the current async procedure for the next ## ``ms`` milliseconds. diff --git a/lib/pure/asyncfile.nim b/lib/pure/asyncfile.nim index c58e6c11b..8fb30075c 100644 --- a/lib/pure/asyncfile.nim +++ b/lib/pure/asyncfile.nim @@ -70,14 +70,16 @@ else: result = O_RDWR result = result or O_NONBLOCK -proc getFileSize(f: AsyncFile): int64 = +proc getFileSize*(f: AsyncFile): int64 = ## Retrieves the specified file's size. when defined(windows) or defined(nimdoc): var high: DWord let low = getFileSize(f.fd.Handle, addr high) if low == INVALID_FILE_SIZE: raiseOSError(osLastError()) - return (high shl 32) or low + result = (high shl 32) or low + else: + result = lseek(f.fd.cint, 0, SEEK_END) proc openAsync*(filename: string, mode = fmRead): AsyncFile = ## Opens a file specified by the path in ``filename`` using @@ -310,7 +312,7 @@ proc setFilePos*(f: AsyncFile, pos: int64) = ## operations. The file's first byte has the index zero. f.offset = pos when not defined(windows) and not defined(nimdoc): - let ret = lseek(f.fd.cint, pos, SEEK_SET) + let ret = lseek(f.fd.cint, pos.Off, SEEK_SET) if ret == -1: raiseOSError(osLastError()) @@ -337,13 +339,17 @@ proc writeBuffer*(f: AsyncFile, buf: pointer, size: int): Future[void] = if not retFuture.finished: if errcode == OSErrorCode(-1): assert bytesCount == size.int32 - f.offset.inc(size) retFuture.complete() else: retFuture.fail(newException(OSError, osErrorMsg(errcode))) ) + # passing -1 here should work according to MSDN, but doesn't. For more + # information see + # http://stackoverflow.com/questions/33650899/does-asynchronous-file- + # appending-in-windows-preserve-order ol.offset = DWord(f.offset and 0xffffffff) ol.offsetHigh = DWord(f.offset shr 32) + f.offset.inc(size) # According to MSDN we're supposed to pass nil to lpNumberOfBytesWritten. let ret = writeFile(f.fd.Handle, buf, size.int32, nil, @@ -362,7 +368,6 @@ proc writeBuffer*(f: AsyncFile, buf: pointer, size: int): Future[void] = retFuture.fail(newException(OSError, osErrorMsg(osLastError()))) else: assert bytesWritten == size.int32 - f.offset.inc(size) retFuture.complete() else: var written = 0 @@ -408,7 +413,6 @@ proc write*(f: AsyncFile, data: string): Future[void] = if not retFuture.finished: if errcode == OSErrorCode(-1): assert bytesCount == data.len.int32 - f.offset.inc(data.len) retFuture.complete() else: retFuture.fail(newException(OSError, osErrorMsg(errcode))) @@ -418,6 +422,7 @@ proc write*(f: AsyncFile, data: string): Future[void] = ) ol.offset = DWord(f.offset and 0xffffffff) ol.offsetHigh = DWord(f.offset shr 32) + f.offset.inc(data.len) # According to MSDN we're supposed to pass nil to lpNumberOfBytesWritten. let ret = writeFile(f.fd.Handle, buffer, data.len.int32, nil, @@ -439,7 +444,6 @@ proc write*(f: AsyncFile, data: string): Future[void] = retFuture.fail(newException(OSError, osErrorMsg(osLastError()))) else: assert bytesWritten == data.len.int32 - f.offset.inc(data.len) retFuture.complete() else: var written = 0 @@ -466,6 +470,23 @@ proc write*(f: AsyncFile, data: string): Future[void] = addWrite(f.fd, cb) return retFuture +proc setFileSize*(f: AsyncFile, length: int64) = + ## Set a file length. + when defined(windows) or defined(nimdoc): + var + high = (length shr 32).Dword + let + low = (length and 0xffffffff).Dword + status = setFilePointer(f.fd.Handle, low, addr high, 0) + lastErr = osLastError() + if (status == INVALID_SET_FILE_POINTER and lastErr.int32 != NO_ERROR) or + (setEndOfFile(f.fd.Handle) == 0): + raiseOSError(osLastError()) + else: + # will truncate if Off is a 32-bit type! + if ftruncate(f.fd.cint, length.Off) == -1: + raiseOSError(osLastError()) + proc close*(f: AsyncFile) = ## Closes the file specified. unregister(f.fd) @@ -498,4 +519,4 @@ proc readToStream*(f: AsyncFile, fs: FutureStream[string]) {.async.} = break await fs.write(data) - fs.complete() \ No newline at end of file + fs.complete() diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index 1ec751a64..9f73bc3cf 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -244,6 +244,17 @@ when defineSsl: else: raiseSSLError("Socket has been disconnected") +proc dial*(address: string, port: Port, protocol = IPPROTO_TCP, + buffered = true): Future[AsyncSocket] {.async.} = + ## Establishes connection to the specified ``address``:``port`` pair via the + ## specified protocol. The procedure iterates through possible + ## resolutions of the ``address`` until it succeeds, meaning that it + ## seamlessly works with both IPv4 and IPv6. + ## Returns AsyncSocket ready to send or receive data. + let asyncFd = await asyncdispatch.dial(address, port, protocol) + let sockType = protocol.toSockType() + let domain = getSockDomain(asyncFd.SocketHandle) + result = newAsyncSocket(asyncFd, domain, sockType, protocol, buffered) proc connect*(socket: AsyncSocket, address: string, port: Port) {.async.} = ## Connects ``socket`` to server at ``address:port``. @@ -636,9 +647,12 @@ when defineSsl: sslSetBio(socket.sslHandle, socket.bioIn, socket.bioOut) proc wrapConnectedSocket*(ctx: SslContext, socket: AsyncSocket, - handshake: SslHandshakeType) = + handshake: SslHandshakeType, + hostname: string = nil) = ## Wraps a connected socket in an SSL context. This function effectively ## turns ``socket`` into an SSL socket. + ## ``hostname`` should be specified so that the client knows which hostname + ## the server certificate should be validated against. ## ## This should be called on a connected socket, and will perform ## an SSL handshake immediately. @@ -649,6 +663,10 @@ when defineSsl: case handshake of handshakeAsClient: + if not hostname.isNil and not isIpAddress(hostname): + # Set the SNI address for this connection. This call can fail if + # we're not using TLSv1+. + discard SSL_set_tlsext_host_name(socket.sslHandle, hostname) sslSetConnectState(socket.sslHandle) of handshakeAsServer: sslSetAcceptState(socket.sslHandle) diff --git a/lib/pure/base64.nim b/lib/pure/base64.nim index eee03d7ae..4b0d08292 100644 --- a/lib/pure/base64.nim +++ b/lib/pure/base64.nim @@ -44,21 +44,23 @@ const cb64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" -template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediate.} = +template encodeInternal(s: typed, lineLen: int, newLine: string): untyped = ## encodes `s` into base64 representation. After `lineLen` characters, a ## `newline` is added. var total = ((len(s) + 2) div 3) * 4 - var numLines = (total + lineLen - 1) div lineLen + let numLines = (total + lineLen - 1) div lineLen if numLines > 0: inc(total, (numLines - 1) * newLine.len) result = newString(total) - var i = 0 - var r = 0 - var currLine = 0 + var + i = 0 + r = 0 + currLine = 0 while i < s.len - 2: - var a = ord(s[i]) - var b = ord(s[i+1]) - var c = ord(s[i+2]) + let + a = ord(s[i]) + b = ord(s[i+1]) + c = ord(s[i+2]) result[r] = cb64[a shr 2] result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] result[r+2] = cb64[((b and 0x0F) shl 2) or ((c and 0xC0) shr 6)] @@ -74,8 +76,9 @@ template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediat currLine = 0 if i < s.len-1: - var a = ord(s[i]) - var b = ord(s[i+1]) + let + a = ord(s[i]) + b = ord(s[i+1]) result[r] = cb64[a shr 2] result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] result[r+2] = cb64[((b and 0x0F) shl 2)] @@ -83,7 +86,7 @@ template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediat if r+4 != result.len: setLen(result, r+4) elif i < s.len: - var a = ord(s[i]) + let a = ord(s[i]) result[r] = cb64[a shr 2] result[r+1] = cb64[(a and 3) shl 4] result[r+2] = '=' @@ -127,15 +130,17 @@ proc decode*(s: string): string = # total is an upper bound, as we will skip arbitrary whitespace: result = newString(total) - var i = 0 - var r = 0 + var + i = 0 + r = 0 while true: while s[i] in Whitespace: inc(i) if i < s.len-3: - var a = s[i].decodeByte - var b = s[i+1].decodeByte - var c = s[i+2].decodeByte - var d = s[i+3].decodeByte + let + a = s[i].decodeByte + b = s[i+1].decodeByte + c = s[i+2].decodeByte + d = s[i+3].decodeByte result[r] = chr((a shl 2) and 0xff or ((b shr 4) and 0x03)) result[r+1] = chr((b shl 4) and 0xff or ((c shr 2) and 0x0F)) @@ -169,4 +174,4 @@ when isMainModule: for t in items(tests): assert decode(encode(t)) == t assert decode(encode(t, lineLen=40)) == t - assert decode(encode(t, lineLen=76)) == t \ No newline at end of file + assert decode(encode(t, lineLen=76)) == t diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index b6c00966f..323af5a38 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -269,6 +269,18 @@ proc del*[A, B](t: var Table[A, B], key: A) = ## deletes `key` from hash table `t`. delImpl() +proc take*[A, B](t: var Table[A, B], key: A, val: var B): bool = + ## Deletes the ``key`` from the table. + ## Returns ``true``, if the ``key`` existed, and sets ``val`` to the + ## mapping of the key. Otherwise, returns ``false``, and the ``val`` is + ## unchanged. + var hc: Hash + var index = rawGet(t, key, hc) + result = index >= 0 + if result: + shallowCopy(val, t.data[index].val) + delImplIdx(t, index) + proc enlarge[A, B](t: var Table[A, B]) = var n: KeyValuePairSeq[A, B] newSeq(n, len(t.data) * growthFactor) @@ -424,6 +436,13 @@ proc del*[A, B](t: TableRef[A, B], key: A) = ## deletes `key` from hash table `t`. t[].del(key) +proc take*[A, B](t: TableRef[A, B], key: A, val: var B): bool = + ## Deletes the ``key`` from the table. + ## Returns ``true``, if the ``key`` existed, and sets ``val`` to the + ## mapping of the key. Otherwise, returns ``false``, and the ``val`` is + ## unchanged. + result = t[].take(key, val) + proc newTable*[A, B](initialSize=64): TableRef[A, B] = new(result) result[] = initTable[A, B](initialSize) @@ -625,7 +644,7 @@ proc `==`*[A, B](s, t: OrderedTable[A, B]): bool = while ht >= 0 and hs >= 0: var nxtt = t.data[ht].next var nxts = s.data[hs].next - if isFilled(t.data[ht].hcode) and isFilled(s.data[hs].hcode): + if isFilled(t.data[ht].hcode) and isFilled(s.data[hs].hcode): if (s.data[hs].key != t.data[ht].key) and (s.data[hs].val != t.data[ht].val): return false ht = nxtt @@ -785,7 +804,7 @@ proc sort*[A, B](t: OrderedTableRef[A, B], t[].sort(cmp) proc del*[A, B](t: var OrderedTable[A, B], key: A) = - ## deletes `key` from ordered hash table `t`. O(n) comlexity. + ## deletes `key` from ordered hash table `t`. O(n) complexity. var n: OrderedKeyValuePairSeq[A, B] newSeq(n, len(t.data)) var h = t.first @@ -804,7 +823,7 @@ proc del*[A, B](t: var OrderedTable[A, B], key: A) = h = nxt proc del*[A, B](t: var OrderedTableRef[A, B], key: A) = - ## deletes `key` from ordered hash table `t`. O(n) comlexity. + ## deletes `key` from ordered hash table `t`. O(n) complexity. t[].del(key) # ------------------------------ count tables ------------------------------- @@ -829,7 +848,7 @@ proc clear*[A](t: CountTableRef[A]) = proc clear*[A](t: var CountTable[A]) = ## Resets the table so that it is empty. clearImpl() - + iterator pairs*[A](t: CountTable[A]): (A, int) = ## iterates over any (key, value) pair in the table `t`. for h in 0..high(t.data): @@ -1256,17 +1275,17 @@ when isMainModule: var b = newOrderedTable[string, string](initialSize=2) b.add("wrong?", "foo") b.add("wrong?", "foo2") - assert a == b + assert a == b block: #5482 - var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable() + var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable() var b = newOrderedTable[string, string](initialSize=2) b.add("wrong?", "foo") b.add("wrong?", "foo2") - assert a == b + assert a == b block: #5487 - var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable() + var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable() var b = newOrderedTable[string, string]() # notice, default size! b.add("wrong?", "foo") b.add("wrong?", "foo2") @@ -1279,13 +1298,13 @@ when isMainModule: b.add("wrong?", "foo2") assert a == b - block: - var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable() - var b = [("wrong?","foo"), ("wrong?", "foo2")].newOrderedTable() + block: + var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable() + var b = [("wrong?","foo"), ("wrong?", "foo2")].newOrderedTable() var c = newOrderedTable[string, string]() # notice, default size! c.add("wrong?", "foo") - c.add("wrong?", "foo2") + c.add("wrong?", "foo2") assert a == b assert a == c - + diff --git a/lib/pure/cookies.nim b/lib/pure/cookies.nim index 8090cd49d..7d850798c 100644 --- a/lib/pure/cookies.nim +++ b/lib/pure/cookies.nim @@ -39,7 +39,7 @@ proc setCookie*(key, value: string, domain = "", path = "", if domain != "": result.add("; Domain=" & domain) if path != "": result.add("; Path=" & path) if expires != "": result.add("; Expires=" & expires) - if secure: result.add("; secure") + if secure: result.add("; Secure") if httpOnly: result.add("; HttpOnly") proc setCookie*(key, value: string, expires: TimeInfo, @@ -50,7 +50,7 @@ proc setCookie*(key, value: string, expires: TimeInfo, ## ## **Note:** UTC is assumed as the timezone for ``expires``. return setCookie(key, value, domain, path, - format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'UTC'"), + format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'GMT'"), noname, secure, httpOnly) when isMainModule: diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 62c7e2067..4f43177a8 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -434,7 +434,7 @@ proc `[]=`*(p: var MultipartData, name: string, ## "<html><head></head><body><p>test</p></body></html>") p.add(name, file.content, file.name, file.contentType) -proc format(p: MultipartData): tuple[header, body: string] = +proc format(p: MultipartData): tuple[contentType, body: string] = if p == nil or p.content == nil or p.content.len == 0: return ("", "") @@ -449,7 +449,7 @@ proc format(p: MultipartData): tuple[header, body: string] = if not found: break - result.header = "Content-Type: multipart/form-data; boundary=" & bound & "\c\L" + result.contentType = "multipart/form-data; boundary=" & bound result.body = "" for s in p.content: result.body.add("--" & bound & "\c\L" & s) @@ -512,7 +512,7 @@ proc request*(url: string, httpMethod: string, extraHeaders = "", raise newException(HttpRequestError, "The proxy server rejected a CONNECT request, " & "so a secure connection could not be established.") - sslContext.wrapConnectedSocket(s, handshakeAsClient) + sslContext.wrapConnectedSocket(s, handshakeAsClient, hostUrl.hostname) else: raise newException(HttpRequestError, "SSL support not available. Cannot connect via proxy over SSL") else: @@ -640,7 +640,7 @@ proc post*(url: string, extraHeaders = "", body = "", ## ``multipart/form-data`` POSTs comfortably. ## ## **Deprecated since version 0.15.0**: use ``HttpClient.post`` instead. - let (mpHeaders, mpBody) = format(multipart) + let (mpContentType, mpBody) = format(multipart) template withNewLine(x): untyped = if x.len > 0 and not x.endsWith("\c\L"): @@ -650,9 +650,12 @@ proc post*(url: string, extraHeaders = "", body = "", var xb = mpBody.withNewLine() & body - var xh = extraHeaders.withNewLine() & mpHeaders.withNewLine() & + var xh = extraHeaders.withNewLine() & withNewLine("Content-Length: " & $len(xb)) + if not multipart.isNil: + xh.add(withNewLine("Content-Type: " & mpContentType)) + result = request(url, httpPOST, xh, xb, sslContext, timeout, userAgent, proxy) var lastURL = url @@ -1030,32 +1033,39 @@ proc newConnection(client: HttpClient | AsyncHttpClient, if client.currentURL.hostname != url.hostname or client.currentURL.scheme != url.scheme or client.currentURL.port != url.port: + let isSsl = url.scheme.toLowerAscii() == "https" + + if isSsl and not defined(ssl): + raise newException(HttpRequestError, + "SSL support is not available. Cannot connect over SSL.") + if client.connected: client.close() - when client is HttpClient: - client.socket = newSocket() - elif client is AsyncHttpClient: - client.socket = newAsyncSocket() - else: {.fatal: "Unsupported client type".} - # TODO: I should be able to write 'net.Port' here... let port = if url.port == "": - if url.scheme.toLower() == "https": + if isSsl: nativesockets.Port(443) else: nativesockets.Port(80) else: nativesockets.Port(url.port.parseInt) - if url.scheme.toLower() == "https": - when defined(ssl): - client.sslContext.wrapSocket(client.socket) - else: - raise newException(HttpRequestError, - "SSL support is not available. Cannot connect over SSL.") + when client is HttpClient: + client.socket = await net.dial(url.hostname, port) + elif client is AsyncHttpClient: + client.socket = await asyncnet.dial(url.hostname, port) + else: {.fatal: "Unsupported client type".} + + when defined(ssl): + if isSsl: + try: + client.sslContext.wrapConnectedSocket( + client.socket, handshakeAsClient, url.hostname) + except: + client.socket.close() + raise getCurrentException() - await client.socket.connect(url.hostname, port) client.currentURL = url client.connected = true @@ -1093,7 +1103,8 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string, raise newException(HttpRequestError, "The proxy server rejected a CONNECT request, " & "so a secure connection could not be established.") - client.sslContext.wrapConnectedSocket(client.socket, handshakeAsClient) + client.sslContext.wrapConnectedSocket( + client.socket, handshakeAsClient, requestUrl.hostname) client.proxy = nil else: raise newException(HttpRequestError, @@ -1188,7 +1199,7 @@ proc post*(client: HttpClient | AsyncHttpClient, url: string, body = "", ## ## This procedure will follow redirects up to a maximum number of redirects ## specified in ``client.maxRedirects``. - let (mpHeader, mpBody) = format(multipart) + let (mpContentType, mpBody) = format(multipart) # TODO: Support FutureStream for `body` parameter. template withNewLine(x): untyped = if x.len > 0 and not x.endsWith("\c\L"): @@ -1199,7 +1210,7 @@ proc post*(client: HttpClient | AsyncHttpClient, url: string, body = "", var headers = newHttpHeaders() if multipart != nil: - headers["Content-Type"] = mpHeader.split(": ")[1] + headers["Content-Type"] = mpContentType headers["Content-Length"] = $len(xb) result = await client.requestAux(url, $HttpPOST, xb, headers) diff --git a/lib/pure/includes/asynccommon.nim b/lib/pure/includes/asynccommon.nim new file mode 100644 index 000000000..a7d2f803f --- /dev/null +++ b/lib/pure/includes/asynccommon.nim @@ -0,0 +1,201 @@ +template newAsyncNativeSocketImpl(domain, sockType, protocol) = + let handle = newNativeSocket(domain, sockType, protocol) + if handle == osInvalidSocket: + raiseOSError(osLastError()) + handle.setBlocking(false) + when defined(macosx): + handle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1) + result = handle.AsyncFD + register(result) + +proc newAsyncNativeSocket*(domain: cint, sockType: cint, + protocol: cint): AsyncFD = + newAsyncNativeSocketImpl(domain, sockType, protocol) + +proc newAsyncNativeSocket*(domain: Domain = Domain.AF_INET, + sockType: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP): AsyncFD = + newAsyncNativeSocketImpl(domain, sockType, protocol) + +when defined(windows) or defined(nimdoc): + proc bindToDomain(handle: SocketHandle, domain: Domain) = + # Extracted into a separate proc, because connect() on Windows requires + # the socket to be initially bound. + template doBind(saddr) = + if bindAddr(handle, cast[ptr SockAddr](addr(saddr)), + sizeof(saddr).SockLen) < 0'i32: + raiseOSError(osLastError()) + + if domain == Domain.AF_INET6: + var saddr: Sockaddr_in6 + saddr.sin6_family = int16(toInt(domain)) + doBind(saddr) + else: + var saddr: Sockaddr_in + saddr.sin_family = int16(toInt(domain)) + doBind(saddr) + + proc doConnect(socket: AsyncFD, addrInfo: ptr AddrInfo): Future[void] = + let retFuture = newFuture[void]("doConnect") + result = retFuture + + var ol = PCustomOverlapped() + GC_ref(ol) + ol.data = CompletionData(fd: socket, cb: + proc (fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + if not retFuture.finished: + if errcode == OSErrorCode(-1): + retFuture.complete() + else: + retFuture.fail(newException(OSError, osErrorMsg(errcode))) + ) + + let ret = connectEx(socket.SocketHandle, addrInfo.ai_addr, + cint(addrInfo.ai_addrlen), nil, 0, nil, + cast[POVERLAPPED](ol)) + if ret: + # Request to connect completed immediately. + retFuture.complete() + # We don't deallocate ``ol`` here because even though this completed + # immediately poll will still be notified about its completion and it + # will free ``ol``. + else: + let lastError = osLastError() + if lastError.int32 != ERROR_IO_PENDING: + # With ERROR_IO_PENDING ``ol`` will be deallocated in ``poll``, + # and the future will be completed/failed there, too. + GC_unref(ol) + retFuture.fail(newException(OSError, osErrorMsg(lastError))) +else: + proc doConnect(socket: AsyncFD, addrInfo: ptr AddrInfo): Future[void] = + let retFuture = newFuture[void]("doConnect") + result = retFuture + + proc cb(fd: AsyncFD): bool = + let ret = SocketHandle(fd).getSockOptInt( + cint(SOL_SOCKET), cint(SO_ERROR)) + if ret == 0: + # We have connected. + retFuture.complete() + return true + elif ret == EINTR: + # interrupted, keep waiting + return false + else: + retFuture.fail(newException(OSError, osErrorMsg(OSErrorCode(ret)))) + return true + + let ret = connect(socket.SocketHandle, + addrInfo.ai_addr, + addrInfo.ai_addrlen.Socklen) + if ret == 0: + # Request to connect completed immediately. + retFuture.complete() + else: + let lastError = osLastError() + if lastError.int32 == EINTR or lastError.int32 == EINPROGRESS: + addWrite(socket, cb) + else: + retFuture.fail(newException(OSError, osErrorMsg(lastError))) + +template asyncAddrInfoLoop(addrInfo: ptr AddrInfo, fd: untyped, + protocol: Protocol = IPPROTO_RAW) = + ## Iterates through the AddrInfo linked list asynchronously + ## until the connection can be established. + const shouldCreateFd = not declared(fd) + + when shouldCreateFd: + let sockType = protocol.toSockType() + + var fdPerDomain: array[low(Domain).ord..high(Domain).ord, AsyncFD] + for i in low(fdPerDomain)..high(fdPerDomain): + fdPerDomain[i] = osInvalidSocket.AsyncFD + template closeUnusedFds(domainToKeep = -1) {.dirty.} = + for i, fd in fdPerDomain: + if fd != osInvalidSocket.AsyncFD and i != domainToKeep: + fd.closeSocket() + + var lastException: ref Exception + var curAddrInfo = addrInfo + var domain: Domain + when shouldCreateFd: + var curFd: AsyncFD + else: + var curFd = fd + proc tryNextAddrInfo(fut: Future[void]) {.gcsafe.} = + if fut == nil or fut.failed: + if fut != nil: + lastException = fut.readError() + + while curAddrInfo != nil: + let domainOpt = curAddrInfo.ai_family.toKnownDomain() + if domainOpt.isSome: + domain = domainOpt.unsafeGet() + break + curAddrInfo = curAddrInfo.ai_next + + if curAddrInfo == nil: + freeAddrInfo(addrInfo) + when shouldCreateFd: + closeUnusedFds() + if lastException != nil: + retFuture.fail(lastException) + else: + retFuture.fail(newException( + IOError, "Couldn't resolve address: " & address)) + return + + when shouldCreateFd: + curFd = fdPerDomain[ord(domain)] + if curFd == osInvalidSocket.AsyncFD: + try: + curFd = newAsyncNativeSocket(domain, sockType, protocol) + except: + freeAddrInfo(addrInfo) + closeUnusedFds() + raise getCurrentException() + when defined(windows): + curFd.SocketHandle.bindToDomain(domain) + fdPerDomain[ord(domain)] = curFd + + doConnect(curFd, curAddrInfo).callback = tryNextAddrInfo + curAddrInfo = curAddrInfo.ai_next + else: + freeAddrInfo(addrInfo) + when shouldCreateFd: + closeUnusedFds(ord(domain)) + retFuture.complete(curFd) + else: + retFuture.complete() + + tryNextAddrInfo(nil) + +proc dial*(address: string, port: Port, + protocol: Protocol = IPPROTO_TCP): Future[AsyncFD] = + ## Establishes connection to the specified ``address``:``port`` pair via the + ## specified protocol. The procedure iterates through possible + ## resolutions of the ``address`` until it succeeds, meaning that it + ## seamlessly works with both IPv4 and IPv6. + ## Returns the async file descriptor, registered in the dispatcher of + ## the current thread, ready to send or receive data. + let retFuture = newFuture[AsyncFD]("dial") + result = retFuture + let sockType = protocol.toSockType() + + let aiList = getAddrInfo(address, port, Domain.AF_UNSPEC, sockType, protocol) + asyncAddrInfoLoop(aiList, noFD, protocol) + +proc connect*(socket: AsyncFD, address: string, port: Port, + domain = Domain.AF_INET): Future[void] = + let retFuture = newFuture[void]("connect") + result = retFuture + + when defined(windows): + verifyPresence(socket) + else: + assert getSockDomain(socket.SocketHandle) == domain + + let aiList = getAddrInfo(address, port, domain) + when defined(windows): + socket.SocketHandle.bindToDomain(domain) + asyncAddrInfoLoop(aiList, socket) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index bacb182b4..564f952d3 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -14,25 +14,56 @@ ## JSON is based on a subset of the JavaScript Programming Language, ## Standard ECMA-262 3rd Edition - December 1999. ## -## Usage example: +## Dynamically retrieving fields from JSON +## ======================================= ## -## .. code-block:: nim -## let -## small_json = """{"test": 1.3, "key2": true}""" -## jobj = parseJson(small_json) -## assert (jobj.kind == JObject)\ -## jobj["test"] = newJFloat(0.7) # create or update -## echo($jobj["test"].fnum) -## echo($jobj["key2"].bval) -## echo jobj{"missing key"}.getFNum(0.1) # read a float value using a default -## jobj{"a", "b", "c"} = newJFloat(3.3) # created nested keys +## This module allows you to access fields in a parsed JSON object in two +## different ways, one of them is described in this section. ## -## Results in: +## The ``parseJson`` procedure takes a string containing JSON and returns a +## ``JsonNode`` object. This is an object variant and it is either a +## ``JObject``, ``JArray``, ``JString``, ``JInt``, ``JFloat``, ``JBool`` or +## ``JNull``. You +## check the kind of this object variant by using the ``kind`` accessor. ## -## .. code-block:: nim +## For a ``JsonNode`` who's kind is ``JObject``, you can acess its fields using +## the ``[]`` operator. The following example shows how to do this: +## +## .. code-block:: Nim +## let jsonNode = parseJson("""{"key": 3.14}""") +## doAssert jsonNode.kind == JObject +## doAssert jsonNode["key"].kind == JFloat +## +## Retrieving the value of a JSON node can then be achieved using one of the +## helper procedures, which include: +## +## * ``getNum`` +## * ``getFNum`` +## * ``getStr`` +## * ``getBVal`` +## +## To retrieve the value of ``"key"`` you can do the following: +## +## .. code-block:: Nim +## doAssert jsonNode["key"].getFNum() == 3.14 +## +## The ``[]`` operator will raise an exception when the specified field does +## not exist. If you wish to avoid this behaviour you can use the ``{}`` +## operator instead, it will simply return ``nil`` when the field is not found. +## The ``get``-family of procedures will return a default value when called on +## ``nil``. +## +## Unmarshalling JSON into a type +## ============================== ## -## 1.3000000000000000e+00 -## true +## This module allows you to access fields in a parsed JSON object in two +## different ways, one of them is described in this section. +## +## This is done using the ``to`` macro. Take a look at +## `its documentation <#to.m,JsonNode,typedesc>`_ to see an example of its use. +## +## Creating JSON +## ============= ## ## This module can also be used to comfortably create JSON using the `%*` ## operator: @@ -124,6 +155,9 @@ type state: seq[ParserState] filename: string + JsonKindError* = object of ValueError ## raised by the ``to`` macro if the + ## JSON kind is incorrect. + {.deprecated: [TJsonEventKind: JsonEventKind, TJsonError: JsonError, TJsonParser: JsonParser, TTokKind: TokKind].} @@ -1179,22 +1213,22 @@ when not defined(js): proc parseJson*(s: Stream, filename: string): JsonNode = ## Parses from a stream `s` into a `JsonNode`. `filename` is only needed ## for nice error messages. - ## If `s` contains extra data, it will raising `JsonParsingError`. + ## If `s` contains extra data, it will raise `JsonParsingError`. var p: JsonParser p.open(s, filename) defer: p.close() discard getTok(p) # read first token result = p.parseJson() - eat(p, tkEof) # check there are no exstra data + eat(p, tkEof) # check if there is no extra data proc parseJson*(buffer: string): JsonNode = ## Parses JSON from `buffer`. - ## If `buffer` contains extra data, it will raising `JsonParsingError`. + ## If `buffer` contains extra data, it will raise `JsonParsingError`. result = parseJson(newStringStream(buffer), "input") proc parseFile*(filename: string): JsonNode = ## Parses `file` into a `JsonNode`. - ## If `file` contains extra data, it will raising `JsonParsingError`. + ## If `file` contains extra data, it will raise `JsonParsingError`. var stream = newFileStream(filename, fmRead) if stream == nil: raise newException(IOError, "cannot read from file: " & filename) @@ -1272,6 +1306,465 @@ else: proc parseJson*(buffer: string): JsonNode = return parseNativeJson(buffer).convertObject() +# -- Json deserialiser macro. -- + +proc createJsonIndexer(jsonNode: NimNode, + index: string | int | NimNode): NimNode + {.compileTime.} = + when index is string: + let indexNode = newStrLitNode(index) + elif index is int: + let indexNode = newIntLitNode(index) + elif index is NimNode: + let indexNode = index + + result = newNimNode(nnkBracketExpr).add( + jsonNode, + indexNode + ) + +template verifyJsonKind(node: JsonNode, kinds: set[JsonNodeKind], + ast: string) = + if node.kind notin kinds: + let msg = "Incorrect JSON kind. Wanted '$1' in '$2' but got '$3'." % [ + $kinds, + ast, + $node.kind + ] + raise newException(JsonKindError, msg) + +proc getEnum(node: JsonNode, ast: string, T: typedesc): T = + when T is SomeInteger: + # TODO: I shouldn't need this proc. + proc convert[T](x: BiggestInt): T = T(x) + verifyJsonKind(node, {JInt}, ast) + return convert[T](node.getNum()) + else: + verifyJsonKind(node, {JString}, ast) + return parseEnum[T](node.getStr()) + +proc toIdentNode(typeNode: NimNode): NimNode = + ## Converts a Sym type node (returned by getType et al.) into an + ## Ident node. Placing Sym type nodes inside the resulting code AST is + ## unsound (according to @Araq) so this is necessary. + case typeNode.kind + of nnkSym: + return newIdentNode($typeNode) + of nnkBracketExpr: + result = typeNode + for i in 0..<len(result): + result[i] = newIdentNode($result[i]) + of nnkIdent: + return typeNode + else: + doAssert false, "Cannot convert typeNode to an ident node: " & $typeNode.kind + +proc createGetEnumCall(jsonNode, kindType: NimNode): NimNode = + # -> getEnum(`jsonNode`, `kindType`) + let getEnumSym = bindSym("getEnum") + let astStrLit = toStrLit(jsonNode) + let getEnumCall = newCall(getEnumSym, jsonNode, astStrLit, kindType) + return getEnumCall + +proc createOfBranchCond(ofBranch, getEnumCall: NimNode): NimNode = + ## Creates an expression that acts as the condition for an ``of`` branch. + var cond = newIdentNode("false") + for ofCond in ofBranch: + if ofCond.kind == nnkRecList: + break + + let comparison = infix(getEnumCall, "==", ofCond) + cond = infix(cond, "or", comparison) + + return cond + +proc processObjField(field, jsonNode: NimNode): seq[NimNode] {.compileTime.} +proc processOfBranch(ofBranch, jsonNode, kindType, + kindJsonNode: NimNode): seq[NimNode] {.compileTime.} = + ## Processes each field inside of an object's ``of`` branch. + ## For each field a new ExprColonExpr node is created and put in the + ## resulting list. + ## + ## Sample ``ofBranch`` AST: + ## + ## .. code-block::plain + ## OfBranch of 0, 1: + ## IntLit 0 foodPos: float + ## IntLit 1 enemyPos: float + ## RecList + ## Sym "foodPos" + ## Sym "enemyPos" + result = @[] + let getEnumCall = createGetEnumCall(kindJsonNode, kindType) + + for branchField in ofBranch[^1]: + let objFields = processObjField(branchField, jsonNode) + + for objField in objFields: + let exprColonExpr = newNimNode(nnkExprColonExpr) + result.add(exprColonExpr) + # Add the name of the field. + exprColonExpr.add(toIdentNode(objField[0])) + + # Add the value of the field. + let cond = createOfBranchCond(ofBranch, getEnumCall) + exprColonExpr.add(newIfStmt( + (cond, objField[1]) + )) + +proc processElseBranch(recCaseNode, elseBranch, jsonNode, kindType, + kindJsonNode: NimNode): seq[NimNode] {.compileTime.} = + ## Processes each field inside of a variant object's ``else`` branch. + ## + ## ..code-block::plain + ## Else + ## RecList + ## Sym "other" + result = @[] + let getEnumCall = createGetEnumCall(kindJsonNode, kindType) + + # We need to build up a list of conditions from each ``of`` branch so that + # we can then negate it to get ``else``. + var cond = newIdentNode("false") + for i in 1 .. <len(recCaseNode): + if recCaseNode[i].kind == nnkElse: + break + + cond = infix(cond, "or", createOfBranchCond(recCaseNode[i], getEnumCall)) + + # Negate the condition. + cond = prefix(cond, "not") + + for branchField in elseBranch[^1]: + let objFields = processObjField(branchField, jsonNode) + + for objField in objFields: + let exprColonExpr = newNimNode(nnkExprColonExpr) + result.add(exprColonExpr) + # Add the name of the field. + exprColonExpr.add(toIdentNode(objField[0])) + + # Add the value of the field. + let ifStmt = newIfStmt((cond, objField[1])) + exprColonExpr.add(ifStmt) + +proc createConstructor(typeSym, jsonNode: NimNode): NimNode {.compileTime.} +proc processObjField(field, jsonNode: NimNode): seq[NimNode] = + ## Process a field from a ``RecList``. + ## + ## The field will typically be a simple ``Sym`` node, but for object variants + ## it may also be a ``RecCase`` in which case things become complicated. + result = @[] + case field.kind + of nnkSym: + # Ordinary field. For example, `name: string`. + let exprColonExpr = newNimNode(nnkExprColonExpr) + result.add(exprColonExpr) + + # Add the field name. + exprColonExpr.add(toIdentNode(field)) + + # Add the field value. + # -> jsonNode["`field`"] + let indexedJsonNode = createJsonIndexer(jsonNode, $field) + exprColonExpr.add(createConstructor(getTypeInst(field), indexedJsonNode)) + + of nnkRecCase: + # A "case" field that introduces a variant. + let exprColonExpr = newNimNode(nnkExprColonExpr) + result.add(exprColonExpr) + + # Add the "case" field name (usually "kind"). + exprColonExpr.add(toIdentNode(field[0])) + + # -> jsonNode["`field[0]`"] + let kindJsonNode = createJsonIndexer(jsonNode, $field[0]) + + # Add the "case" field's value. + let kindType = toIdentNode(getTypeInst(field[0])) + let getEnumSym = bindSym("getEnum") + let astStrLit = toStrLit(kindJsonNode) + let getEnumCall = newCall(getEnumSym, kindJsonNode, astStrLit, kindType) + exprColonExpr.add(getEnumCall) + + # Iterate through each `of` branch. + for i in 1 .. <field.len: + case field[i].kind + of nnkOfBranch: + result.add processOfBranch(field[i], jsonNode, kindType, kindJsonNode) + of nnkElse: + result.add processElseBranch(field, field[i], jsonNode, kindType, kindJsonNode) + else: + doAssert false, "Expected OfBranch or Else node kinds, got: " & $field[i].kind + else: + doAssert false, "Unable to process object field: " & $field.kind + + doAssert result.len > 0 + +proc processType(typeName: NimNode, obj: NimNode, + jsonNode: NimNode, isRef: bool): NimNode {.compileTime.} = + ## Process a type such as ``Sym "float"`` or ``ObjectTy ...``. + ## + ## Sample ``ObjectTy``: + ## + ## .. code-block::plain + ## ObjectTy + ## Empty + ## Empty + ## RecList + ## Sym "events" + case obj.kind + of nnkObjectTy: + # Create object constructor. + result = newNimNode(nnkObjConstr) + result.add(typeName) # Name of the type to construct. + + # Process each object field and add it as an exprColonExpr + expectKind(obj[2], nnkRecList) + for field in obj[2]: + let nodes = processObjField(field, jsonNode) + result.add(nodes) + + # Object might be null. So we need to check for that. + if isRef: + result = quote do: + verifyJsonKind(`jsonNode`, {JObject, JNull}, astToStr(`jsonNode`)) + if `jsonNode`.kind == JNull: + nil + else: + `result` + else: + result = quote do: + verifyJsonKind(`jsonNode`, {JObject}, astToStr(`jsonNode`)); + `result` + + of nnkEnumTy: + let instType = toIdentNode(getTypeInst(typeName)) + let getEnumCall = createGetEnumCall(jsonNode, instType) + result = quote do: + ( + `getEnumCall` + ) + of nnkSym: + case ($typeName).normalize + of "float": + result = quote do: + ( + verifyJsonKind(`jsonNode`, {JFloat, JInt}, astToStr(`jsonNode`)); + if `jsonNode`.kind == JFloat: `jsonNode`.fnum else: `jsonNode`.num.float + ) + of "string": + result = quote do: + ( + verifyJsonKind(`jsonNode`, {JString, JNull}, astToStr(`jsonNode`)); + if `jsonNode`.kind == JNull: nil else: `jsonNode`.str + ) + of "int": + result = quote do: + ( + verifyJsonKind(`jsonNode`, {JInt}, astToStr(`jsonNode`)); + `jsonNode`.num.int + ) + of "biggestint": + result = quote do: + ( + verifyJsonKind(`jsonNode`, {JInt}, astToStr(`jsonNode`)); + `jsonNode`.num + ) + of "bool": + result = quote do: + ( + verifyJsonKind(`jsonNode`, {JBool}, astToStr(`jsonNode`)); + `jsonNode`.bval + ) + else: + doAssert false, "Unable to process nnkSym " & $typeName + else: + doAssert false, "Unable to process type: " & $obj.kind + + doAssert(not result.isNil(), "processType not initialised.") + +proc createConstructor(typeSym, jsonNode: NimNode): NimNode = + ## Accepts a type description, i.e. "ref Type", "seq[Type]", "Type" etc. + ## + ## The ``jsonNode`` refers to the node variable that we are deserialising. + ## + ## Returns an object constructor node. + # echo("--createConsuctor-- \n", treeRepr(typeSym)) + # echo() + + case typeSym.kind + of nnkBracketExpr: + var bracketName = ($typeSym[0]).normalize + case bracketName + of "ref": + # Ref type. + var typeName = $typeSym[1] + # Remove the `:ObjectType` suffix. + if typeName.endsWith(":ObjectType"): + typeName = typeName[0 .. ^12] + + let obj = getType(typeSym[1]) + result = processType(newIdentNode(typeName), obj, jsonNode, true) + of "seq": + let seqT = typeSym[1] + let forLoopI = newIdentNode("i") + let indexerNode = createJsonIndexer(jsonNode, forLoopI) + let constructorNode = createConstructor(seqT, indexerNode) + + # Create a statement expression containing a for loop. + result = quote do: + ( + var list: `typeSym` = @[]; + # if `jsonNode`.kind != JArray: + # # TODO: Improve error message. + # raise newException(ValueError, "Expected a list") + for `forLoopI` in 0 .. <`jsonNode`.len: list.add(`constructorNode`); + list + ) + else: + # Generic type. + let obj = getType(typeSym) + result = processType(typeSym, obj, jsonNode, false) + of nnkSym: + let obj = getType(typeSym) + if obj.kind == nnkBracketExpr: + # When `Sym "Foo"` turns out to be a `ref object`. + result = createConstructor(obj, jsonNode) + else: + result = processType(typeSym, obj, jsonNode, false) + else: + doAssert false, "Unable to create constructor for: " & $typeSym.kind + + doAssert(not result.isNil(), "Constructor not initialised.") + +proc postProcess(node: NimNode): NimNode +proc postProcessValue(value: NimNode): NimNode = + ## Looks for object constructors and calls the ``postProcess`` procedure + ## on them. Otherwise it just returns the node as-is. + case value.kind + of nnkObjConstr: + result = postProcess(value) + else: + result = value + for i in 0 .. <len(result): + result[i] = postProcessValue(result[i]) + +proc postProcessExprColonExpr(exprColonExpr, resIdent: NimNode): NimNode = + ## Transform each field mapping in the ExprColonExpr into a simple + ## field assignment. Special processing is performed if the field mapping + ## has an if statement. + ## + ## ..code-block::plain + ## field: (if true: 12) -> if true: `resIdent`.field = 12 + expectKind(exprColonExpr, nnkExprColonExpr) + let fieldName = exprColonExpr[0] + let fieldValue = exprColonExpr[1] + case fieldValue.kind + of nnkIfStmt: + doAssert fieldValue.len == 1, "Cannot postProcess two ElifBranches." + expectKind(fieldValue[0], nnkElifBranch) + + let cond = fieldValue[0][0] + let bodyValue = postProcessValue(fieldValue[0][1]) + doAssert(bodyValue.kind != nnkNilLit) + result = + quote do: + if `cond`: + `resIdent`.`fieldName` = `bodyValue` + else: + let fieldValue = postProcessValue(fieldValue) + doAssert(fieldValue.kind != nnkNilLit) + result = + quote do: + `resIdent`.`fieldName` = `fieldValue` + + +proc postProcess(node: NimNode): NimNode = + ## The ``createConstructor`` proc creates a ObjConstr node which contains + ## if statements for fields that may not be assignable (due to an object + ## variant). Nim doesn't handle this, but may do in the future. + ## + ## For simplicity, we post process the object constructor into multiple + ## assignments. + ## + ## For example: + ## + ## ..code-block::plain + ## Object( (var res = Object(); + ## field: if true: 12 -> if true: res.field = 12; + ## ) res) + result = newNimNode(nnkStmtListExpr) + + expectKind(node, nnkObjConstr) + + # Create the type. + # -> var res = Object() + var resIdent = genSym(nskVar, "res") + # TODO: Placing `node[0]` inside quote is buggy + var resType = toIdentNode(node[0]) + + result.add( + quote do: + var `resIdent` = `resType`(); + ) + + # Process each ExprColonExpr. + for i in 1..<len(node): + result.add postProcessExprColonExpr(node[i], resIdent) + + # Return the `res` variable. + result.add( + quote do: + `resIdent` + ) + + +macro to*(node: JsonNode, T: typedesc): untyped = + ## `Unmarshals`:idx: the specified node into the object type specified. + ## + ## Known limitations: + ## + ## * Heterogeneous arrays are not supported. + ## * Sets in object variants are not supported. + ## + ## Example: + ## + ## .. code-block:: Nim + ## let jsonNode = parseJson(""" + ## { + ## "person": { + ## "name": "Nimmer", + ## "age": 21 + ## }, + ## "list": [1, 2, 3, 4] + ## } + ## """) + ## + ## type + ## Person = object + ## name: string + ## age: int + ## + ## Data = object + ## person: Person + ## list: seq[int] + ## + ## var data = to(jsonNode, Data) + ## doAssert data.person.name == "Nimmer" + ## doAssert data.person.age == 21 + ## doAssert data.list == @[1, 2, 3, 4] + + let typeNode = getType(T) + expectKind(typeNode, nnkBracketExpr) + doAssert(($typeNode[0]).normalize == "typedesc") + + result = createConstructor(typeNode[1], node) + # TODO: Rename postProcessValue and move it (?) + result = postProcessValue(result) + + # echo(toStrLit(result)) + when false: import os var s = newFileStream(paramStr(1), fmRead) @@ -1300,6 +1793,7 @@ when false: # To get that we shall use, obj["json"] when isMainModule: + # Note: Macro tests are in tests/stdlib/tjsonmacro.nim let testJson = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd", "c": "\ud83c\udf83", "d": "\u00E6"}""" # nil passthrough diff --git a/lib/pure/nativesockets.nim b/lib/pure/nativesockets.nim index 0a7ffb3b3..7568408a6 100644 --- a/lib/pure/nativesockets.nim +++ b/lib/pure/nativesockets.nim @@ -12,7 +12,7 @@ # TODO: Clean up the exports a bit and everything else in general. -import os +import os, options when hostOS == "solaris": {.passl: "-lsocket -lnsl".} @@ -52,9 +52,11 @@ type Domain* = enum ## domain, which specifies the protocol family of the ## created socket. Other domains than those that are listed ## here are unsupported. - AF_UNIX, ## for local socket (using a file). Unsupported on Windows. + AF_UNSPEC = 0, ## unspecified domain (can be detected automatically by + ## some procedures, such as getaddrinfo) + AF_UNIX = 1, ## for local socket (using a file). Unsupported on Windows. AF_INET = 2, ## for network protocol IPv4 or - AF_INET6 = 23 ## for network protocol IPv6. + AF_INET6 = when defined(macosx): 30 else: 23 ## for network protocol IPv6. SockType* = enum ## second argument to `socket` proc SOCK_STREAM = 1, ## reliable stream-oriented service or Stream Sockets @@ -113,7 +115,7 @@ proc `==`*(a, b: Port): bool {.borrow.} proc `$`*(p: Port): string {.borrow.} ## returns the port number as a string -proc toInt*(domain: Domain): cint +proc toInt*(domain: Domain): cshort ## Converts the Domain enum to a platform-dependent ``cint``. proc toInt*(typ: SockType): cint @@ -123,12 +125,21 @@ proc toInt*(p: Protocol): cint ## Converts the Protocol enum to a platform-dependent ``cint``. when not useWinVersion: - proc toInt(domain: Domain): cint = + proc toInt(domain: Domain): cshort = case domain - of AF_UNIX: result = posix.AF_UNIX - of AF_INET: result = posix.AF_INET - of AF_INET6: result = posix.AF_INET6 - else: discard + of AF_UNSPEC: result = posix.AF_UNSPEC.cshort + of AF_UNIX: result = posix.AF_UNIX.cshort + of AF_INET: result = posix.AF_INET.cshort + of AF_INET6: result = posix.AF_INET6.cshort + + proc toKnownDomain*(family: cint): Option[Domain] = + ## Converts the platform-dependent ``cint`` to the Domain or none(), + ## if the ``cint`` is not known. + result = if family == posix.AF_UNSPEC: some(Domain.AF_UNSPEC) + elif family == posix.AF_UNIX: some(Domain.AF_UNIX) + elif family == posix.AF_INET: some(Domain.AF_INET) + elif family == posix.AF_INET6: some(Domain.AF_INET6) + else: none(Domain) proc toInt(typ: SockType): cint = case typ @@ -136,7 +147,6 @@ when not useWinVersion: of SOCK_DGRAM: result = posix.SOCK_DGRAM of SOCK_SEQPACKET: result = posix.SOCK_SEQPACKET of SOCK_RAW: result = posix.SOCK_RAW - else: discard proc toInt(p: Protocol): cint = case p @@ -146,18 +156,33 @@ when not useWinVersion: of IPPROTO_IPV6: result = posix.IPPROTO_IPV6 of IPPROTO_RAW: result = posix.IPPROTO_RAW of IPPROTO_ICMP: result = posix.IPPROTO_ICMP - else: discard else: - proc toInt(domain: Domain): cint = + proc toInt(domain: Domain): cshort = result = toU16(ord(domain)) + proc toKnownDomain*(family: cint): Option[Domain] = + ## Converts the platform-dependent ``cint`` to the Domain or none(), + ## if the ``cint`` is not known. + result = if family == winlean.AF_UNSPEC: some(Domain.AF_UNSPEC) + elif family == winlean.AF_INET: some(Domain.AF_INET) + elif family == winlean.AF_INET6: some(Domain.AF_INET6) + else: none(Domain) + proc toInt(typ: SockType): cint = result = cint(ord(typ)) proc toInt(p: Protocol): cint = result = cint(ord(p)) +proc toSockType*(protocol: Protocol): SockType = + result = case protocol + of IPPROTO_TCP: + SOCK_STREAM + of IPPROTO_UDP: + SOCK_DGRAM + of IPPROTO_IP, IPPROTO_IPV6, IPPROTO_RAW, IPPROTO_ICMP: + SOCK_RAW proc newNativeSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM, @@ -239,7 +264,7 @@ template ntohl*(x: int32): untyped {.deprecated.} = ## **Warning**: This template is deprecated since 0.14.0, IPv4 ## addresses are now treated as unsigned integers. Please use the unsigned ## version of this template. - cast[int32](ntohl(cast[uint32](x))) + cast[int32](nativesockets.ntohl(cast[uint32](x))) proc ntohs*(x: uint16): uint16 = ## Converts 16-bit unsigned integers from network to host byte order. On @@ -255,7 +280,7 @@ template ntohs*(x: int16): untyped {.deprecated.} = ## **Warning**: This template is deprecated since 0.14.0, where port ## numbers became unsigned integers. Please use the unsigned version of ## this template. - cast[int16](ntohs(cast[uint16](x))) + cast[int16](nativesockets.ntohs(cast[uint16](x))) template htonl*(x: int32): untyped {.deprecated.} = ## Converts 32-bit integers from host to network byte order. On machines @@ -392,14 +417,14 @@ proc getHostname*(): string {.tags: [ReadIOEffect].} = proc getSockDomain*(socket: SocketHandle): Domain = ## returns the socket's domain (AF_INET or AF_INET6). - var name: SockAddr + var name: Sockaddr_in6 var namelen = sizeof(name).SockLen if getsockname(socket, cast[ptr SockAddr](addr(name)), addr(namelen)) == -1'i32: raiseOSError(osLastError()) - if name.sa_family == nativeAfInet: + if name.sin6_family == nativeAfInet: result = AF_INET - elif name.sa_family == nativeAfInet6: + elif name.sin6_family == nativeAfInet6: result = AF_INET6 else: raiseOSError(osLastError(), "unknown socket family in getSockFamily") @@ -410,17 +435,23 @@ proc getAddrString*(sockAddr: ptr SockAddr): string = if sockAddr.sa_family == nativeAfInet: result = $inet_ntoa(cast[ptr Sockaddr_in](sockAddr).sin_addr) elif sockAddr.sa_family == nativeAfInet6: + let addrLen = when not useWinVersion: posix.INET6_ADDRSTRLEN + else: 46 # it's actually 46 in both cases + result = newString(addrLen) + let addr6 = addr cast[ptr Sockaddr_in6](sockAddr).sin6_addr when not useWinVersion: - # TODO: Windows - result = newString(posix.INET6_ADDRSTRLEN) - let addr6 = addr cast[ptr Sockaddr_in6](sockAddr).sin6_addr - discard posix.inet_ntop(posix.AF_INET6, addr6, result.cstring, - result.len.int32) + if posix.inet_ntop(posix.AF_INET6, addr6, addr result[0], + result.len.int32) == nil: + raiseOSError(osLastError()) if posix.IN6_IS_ADDR_V4MAPPED(addr6) != 0: result = result.substr("::ffff:".len) + else: + if winlean.inet_ntop(winlean.AF_INET6, addr6, addr result[0], + result.len.int32) == nil: + raiseOSError(osLastError()) + setLen(result, len(cstring(result))) else: - raiseOSError(osLastError(), "unknown socket family in getAddrString") - + raise newException(IOError, "Unknown socket family in getAddrString") proc getSockName*(socket: SocketHandle): Port = ## returns the socket's associated port number. diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 56f8b9399..629e916fa 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -66,7 +66,7 @@ ## {.deadCodeElim: on.} -import nativesockets, os, strutils, parseutils, times, sets +import nativesockets, os, strutils, parseutils, times, sets, options export Port, `$`, `==` export Domain, SockType, Protocol @@ -237,6 +237,180 @@ proc newSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM, raiseOSError(osLastError()) result = newSocket(fd, domain, sockType, protocol, buffered) +proc parseIPv4Address(address_str: string): IpAddress = + ## Parses IPv4 adresses + ## Raises EInvalidValue on errors + var + byteCount = 0 + currentByte:uint16 = 0 + seperatorValid = false + + result.family = IpAddressFamily.IPv4 + + for i in 0 .. high(address_str): + if address_str[i] in strutils.Digits: # Character is a number + currentByte = currentByte * 10 + + cast[uint16](ord(address_str[i]) - ord('0')) + if currentByte > 255'u16: + raise newException(ValueError, + "Invalid IP Address. Value is out of range") + seperatorValid = true + elif address_str[i] == '.': # IPv4 address separator + if not seperatorValid or byteCount >= 3: + raise newException(ValueError, + "Invalid IP Address. The address consists of too many groups") + result.address_v4[byteCount] = cast[uint8](currentByte) + currentByte = 0 + byteCount.inc + seperatorValid = false + else: + raise newException(ValueError, + "Invalid IP Address. Address contains an invalid character") + + if byteCount != 3 or not seperatorValid: + raise newException(ValueError, "Invalid IP Address") + result.address_v4[byteCount] = cast[uint8](currentByte) + +proc parseIPv6Address(address_str: string): IpAddress = + ## Parses IPv6 adresses + ## Raises EInvalidValue on errors + result.family = IpAddressFamily.IPv6 + if address_str.len < 2: + raise newException(ValueError, "Invalid IP Address") + + var + groupCount = 0 + currentGroupStart = 0 + currentShort:uint32 = 0 + seperatorValid = true + dualColonGroup = -1 + lastWasColon = false + v4StartPos = -1 + byteCount = 0 + + for i,c in address_str: + if c == ':': + if not seperatorValid: + raise newException(ValueError, + "Invalid IP Address. Address contains an invalid seperator") + if lastWasColon: + if dualColonGroup != -1: + raise newException(ValueError, + "Invalid IP Address. Address contains more than one \"::\" seperator") + dualColonGroup = groupCount + seperatorValid = false + elif i != 0 and i != high(address_str): + if groupCount >= 8: + raise newException(ValueError, + "Invalid IP Address. The address consists of too many groups") + result.address_v6[groupCount*2] = cast[uint8](currentShort shr 8) + result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF) + currentShort = 0 + groupCount.inc() + if dualColonGroup != -1: seperatorValid = false + elif i == 0: # only valid if address starts with :: + if address_str[1] != ':': + raise newException(ValueError, + "Invalid IP Address. Address may not start with \":\"") + else: # i == high(address_str) - only valid if address ends with :: + if address_str[high(address_str)-1] != ':': + raise newException(ValueError, + "Invalid IP Address. Address may not end with \":\"") + lastWasColon = true + currentGroupStart = i + 1 + elif c == '.': # Switch to parse IPv4 mode + if i < 3 or not seperatorValid or groupCount >= 7: + raise newException(ValueError, "Invalid IP Address") + v4StartPos = currentGroupStart + currentShort = 0 + seperatorValid = false + break + elif c in strutils.HexDigits: + if c in strutils.Digits: # Normal digit + currentShort = (currentShort shl 4) + cast[uint32](ord(c) - ord('0')) + elif c >= 'a' and c <= 'f': # Lower case hex + currentShort = (currentShort shl 4) + cast[uint32](ord(c) - ord('a')) + 10 + else: # Upper case hex + currentShort = (currentShort shl 4) + cast[uint32](ord(c) - ord('A')) + 10 + if currentShort > 65535'u32: + raise newException(ValueError, + "Invalid IP Address. Value is out of range") + lastWasColon = false + seperatorValid = true + else: + raise newException(ValueError, + "Invalid IP Address. Address contains an invalid character") + + + if v4StartPos == -1: # Don't parse v4. Copy the remaining v6 stuff + if seperatorValid: # Copy remaining data + if groupCount >= 8: + raise newException(ValueError, + "Invalid IP Address. The address consists of too many groups") + result.address_v6[groupCount*2] = cast[uint8](currentShort shr 8) + result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF) + groupCount.inc() + else: # Must parse IPv4 address + for i,c in address_str[v4StartPos..high(address_str)]: + if c in strutils.Digits: # Character is a number + currentShort = currentShort * 10 + cast[uint32](ord(c) - ord('0')) + if currentShort > 255'u32: + raise newException(ValueError, + "Invalid IP Address. Value is out of range") + seperatorValid = true + elif c == '.': # IPv4 address separator + if not seperatorValid or byteCount >= 3: + raise newException(ValueError, "Invalid IP Address") + result.address_v6[groupCount*2 + byteCount] = cast[uint8](currentShort) + currentShort = 0 + byteCount.inc() + seperatorValid = false + else: # Invalid character + raise newException(ValueError, + "Invalid IP Address. Address contains an invalid character") + + if byteCount != 3 or not seperatorValid: + raise newException(ValueError, "Invalid IP Address") + result.address_v6[groupCount*2 + byteCount] = cast[uint8](currentShort) + groupCount += 2 + + # Shift and fill zeros in case of :: + if groupCount > 8: + raise newException(ValueError, + "Invalid IP Address. The address consists of too many groups") + elif groupCount < 8: # must fill + if dualColonGroup == -1: + raise newException(ValueError, + "Invalid IP Address. The address consists of too few groups") + var toFill = 8 - groupCount # The number of groups to fill + var toShift = groupCount - dualColonGroup # Nr of known groups after :: + for i in 0..2*toShift-1: # shift + result.address_v6[15-i] = result.address_v6[groupCount*2-i-1] + for i in 0..2*toFill-1: # fill with 0s + result.address_v6[dualColonGroup*2+i] = 0 + elif dualColonGroup != -1: + raise newException(ValueError, + "Invalid IP Address. The address consists of too many groups") + +proc parseIpAddress*(address_str: string): IpAddress = + ## Parses an IP address + ## Raises EInvalidValue on error + if address_str == nil: + raise newException(ValueError, "IP Address string is nil") + if address_str.contains(':'): + return parseIPv6Address(address_str) + else: + return parseIPv4Address(address_str) + +proc isIpAddress*(address_str: string): bool {.tags: [].} = + ## Checks if a string is an IP address + ## Returns true if it is, false otherwise + try: + discard parseIpAddress(address_str) + except ValueError: + return false + return true + when defineSsl: CRYPTO_malloc_init() SslLibraryInit() @@ -438,9 +612,12 @@ when defineSsl: raiseSSLError() proc wrapConnectedSocket*(ctx: SSLContext, socket: Socket, - handshake: SslHandshakeType) = + handshake: SslHandshakeType, + hostname: string = nil) = ## Wraps a connected socket in an SSL context. This function effectively ## turns ``socket`` into an SSL socket. + ## ``hostname`` should be specified so that the client knows which hostname + ## the server certificate should be validated against. ## ## This should be called on a connected socket, and will perform ## an SSL handshake immediately. @@ -450,6 +627,10 @@ when defineSsl: wrapSocket(ctx, socket) case handshake of handshakeAsClient: + if not hostname.isNil and not isIpAddress(hostname): + # Discard result in case OpenSSL version doesn't support SNI, or we're + # not using TLSv1+ + discard SSL_set_tlsext_host_name(socket.sslHandle, hostname) let ret = SSLConnect(socket.sslHandle) socketError(socket, ret) of handshakeAsServer: @@ -669,7 +850,7 @@ proc close*(socket: Socket) = ## Closes a socket. try: when defineSsl: - if socket.isSSL: + if socket.isSSL and socket.sslHandle != nil: ErrClearError() # As we are closing the underlying socket immediately afterwards, # it is valid, under the TLS standard, to perform a unidirectional @@ -1302,181 +1483,63 @@ proc `$`*(address: IpAddress): string = mask = mask shr 4 printedLastGroup = true -proc parseIPv4Address(address_str: string): IpAddress = - ## Parses IPv4 adresses - ## Raises EInvalidValue on errors - var - byteCount = 0 - currentByte:uint16 = 0 - seperatorValid = false +proc dial*(address: string, port: Port, + protocol = IPPROTO_TCP, buffered = true): Socket + {.tags: [ReadIOEffect, WriteIOEffect].} = + ## Establishes connection to the specified ``address``:``port`` pair via the + ## specified protocol. The procedure iterates through possible + ## resolutions of the ``address`` until it succeeds, meaning that it + ## seamlessly works with both IPv4 and IPv6. + ## Returns Socket ready to send or receive data. + let sockType = protocol.toSockType() + + let aiList = getAddrInfo(address, port, AF_UNSPEC, sockType, protocol) + + var fdPerDomain: array[low(Domain).ord..high(Domain).ord, SocketHandle] + for i in low(fdPerDomain)..high(fdPerDomain): + fdPerDomain[i] = osInvalidSocket + template closeUnusedFds(domainToKeep = -1) {.dirty.} = + for i, fd in fdPerDomain: + if fd != osInvalidSocket and i != domainToKeep: + fd.close() - result.family = IpAddressFamily.IPv4 - - for i in 0 .. high(address_str): - if address_str[i] in strutils.Digits: # Character is a number - currentByte = currentByte * 10 + - cast[uint16](ord(address_str[i]) - ord('0')) - if currentByte > 255'u16: - raise newException(ValueError, - "Invalid IP Address. Value is out of range") - seperatorValid = true - elif address_str[i] == '.': # IPv4 address separator - if not seperatorValid or byteCount >= 3: - raise newException(ValueError, - "Invalid IP Address. The address consists of too many groups") - result.address_v4[byteCount] = cast[uint8](currentByte) - currentByte = 0 - byteCount.inc - seperatorValid = false - else: - raise newException(ValueError, - "Invalid IP Address. Address contains an invalid character") - - if byteCount != 3 or not seperatorValid: - raise newException(ValueError, "Invalid IP Address") - result.address_v4[byteCount] = cast[uint8](currentByte) - -proc parseIPv6Address(address_str: string): IpAddress = - ## Parses IPv6 adresses - ## Raises EInvalidValue on errors - result.family = IpAddressFamily.IPv6 - if address_str.len < 2: - raise newException(ValueError, "Invalid IP Address") - - var - groupCount = 0 - currentGroupStart = 0 - currentShort:uint32 = 0 - seperatorValid = true - dualColonGroup = -1 - lastWasColon = false - v4StartPos = -1 - byteCount = 0 - - for i,c in address_str: - if c == ':': - if not seperatorValid: - raise newException(ValueError, - "Invalid IP Address. Address contains an invalid seperator") - if lastWasColon: - if dualColonGroup != -1: - raise newException(ValueError, - "Invalid IP Address. Address contains more than one \"::\" seperator") - dualColonGroup = groupCount - seperatorValid = false - elif i != 0 and i != high(address_str): - if groupCount >= 8: - raise newException(ValueError, - "Invalid IP Address. The address consists of too many groups") - result.address_v6[groupCount*2] = cast[uint8](currentShort shr 8) - result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF) - currentShort = 0 - groupCount.inc() - if dualColonGroup != -1: seperatorValid = false - elif i == 0: # only valid if address starts with :: - if address_str[1] != ':': - raise newException(ValueError, - "Invalid IP Address. Address may not start with \":\"") - else: # i == high(address_str) - only valid if address ends with :: - if address_str[high(address_str)-1] != ':': - raise newException(ValueError, - "Invalid IP Address. Address may not end with \":\"") - lastWasColon = true - currentGroupStart = i + 1 - elif c == '.': # Switch to parse IPv4 mode - if i < 3 or not seperatorValid or groupCount >= 7: - raise newException(ValueError, "Invalid IP Address") - v4StartPos = currentGroupStart - currentShort = 0 - seperatorValid = false + var success = false + var lastError: OSErrorCode + var it = aiList + var domain: Domain + var lastFd: SocketHandle + while it != nil: + let domainOpt = it.ai_family.toKnownDomain() + if domainOpt.isNone: + it = it.ai_next + continue + domain = domainOpt.unsafeGet() + lastFd = fdPerDomain[ord(domain)] + if lastFd == osInvalidSocket: + lastFd = newNativeSocket(domain, sockType, protocol) + if lastFd == osInvalidSocket: + # we always raise if socket creation failed, because it means a + # network system problem (e.g. not enough FDs), and not an unreachable + # address. + let err = osLastError() + freeAddrInfo(aiList) + closeUnusedFds() + raiseOSError(err) + fdPerDomain[ord(domain)] = lastFd + if connect(lastFd, it.ai_addr, it.ai_addrlen.SockLen) == 0'i32: + success = true break - elif c in strutils.HexDigits: - if c in strutils.Digits: # Normal digit - currentShort = (currentShort shl 4) + cast[uint32](ord(c) - ord('0')) - elif c >= 'a' and c <= 'f': # Lower case hex - currentShort = (currentShort shl 4) + cast[uint32](ord(c) - ord('a')) + 10 - else: # Upper case hex - currentShort = (currentShort shl 4) + cast[uint32](ord(c) - ord('A')) + 10 - if currentShort > 65535'u32: - raise newException(ValueError, - "Invalid IP Address. Value is out of range") - lastWasColon = false - seperatorValid = true - else: - raise newException(ValueError, - "Invalid IP Address. Address contains an invalid character") - - - if v4StartPos == -1: # Don't parse v4. Copy the remaining v6 stuff - if seperatorValid: # Copy remaining data - if groupCount >= 8: - raise newException(ValueError, - "Invalid IP Address. The address consists of too many groups") - result.address_v6[groupCount*2] = cast[uint8](currentShort shr 8) - result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF) - groupCount.inc() - else: # Must parse IPv4 address - for i,c in address_str[v4StartPos..high(address_str)]: - if c in strutils.Digits: # Character is a number - currentShort = currentShort * 10 + cast[uint32](ord(c) - ord('0')) - if currentShort > 255'u32: - raise newException(ValueError, - "Invalid IP Address. Value is out of range") - seperatorValid = true - elif c == '.': # IPv4 address separator - if not seperatorValid or byteCount >= 3: - raise newException(ValueError, "Invalid IP Address") - result.address_v6[groupCount*2 + byteCount] = cast[uint8](currentShort) - currentShort = 0 - byteCount.inc() - seperatorValid = false - else: # Invalid character - raise newException(ValueError, - "Invalid IP Address. Address contains an invalid character") - - if byteCount != 3 or not seperatorValid: - raise newException(ValueError, "Invalid IP Address") - result.address_v6[groupCount*2 + byteCount] = cast[uint8](currentShort) - groupCount += 2 - - # Shift and fill zeros in case of :: - if groupCount > 8: - raise newException(ValueError, - "Invalid IP Address. The address consists of too many groups") - elif groupCount < 8: # must fill - if dualColonGroup == -1: - raise newException(ValueError, - "Invalid IP Address. The address consists of too few groups") - var toFill = 8 - groupCount # The number of groups to fill - var toShift = groupCount - dualColonGroup # Nr of known groups after :: - for i in 0..2*toShift-1: # shift - result.address_v6[15-i] = result.address_v6[groupCount*2-i-1] - for i in 0..2*toFill-1: # fill with 0s - result.address_v6[dualColonGroup*2+i] = 0 - elif dualColonGroup != -1: - raise newException(ValueError, - "Invalid IP Address. The address consists of too many groups") - + lastError = osLastError() + it = it.ai_next + freeAddrInfo(aiList) + closeUnusedFds(ord(domain)) -proc parseIpAddress*(address_str: string): IpAddress = - ## Parses an IP address - ## Raises EInvalidValue on error - if address_str == nil: - raise newException(ValueError, "IP Address string is nil") - if address_str.contains(':'): - return parseIPv6Address(address_str) + if success: + result = newSocket(lastFd, domain, sockType, protocol) + elif lastError != 0.OSErrorCode: + raiseOSError(lastError) else: - return parseIPv4Address(address_str) - -proc isIpAddress*(address_str: string): bool {.tags: [].} = - ## Checks if a string is an IP address - ## Returns true if it is, false otherwise - try: - discard parseIpAddress(address_str) - except ValueError: - return false - return true - + raise newException(IOError, "Couldn't resolve address: " & address) proc connect*(socket: Socket, address: string, port = Port(0)) {.tags: [ReadIOEffect].} = diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim index e4c97b260..60b53dbe0 100644 --- a/lib/pure/oids.nim +++ b/lib/pure/oids.nim @@ -69,10 +69,9 @@ var proc genOid*(): Oid = ## generates a new OID. proc rand(): cint {.importc: "rand", header: "<stdlib.h>", nodecl.} - proc gettime(dummy: ptr cint): cint {.importc: "time", header: "<time.h>".} proc srand(seed: cint) {.importc: "srand", header: "<stdlib.h>", nodecl.} - var t = gettime(nil) + var t = getTime().int32 var i = int32(atomicInc(incr)) diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 82acb2a59..98b6aa309 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1716,7 +1716,7 @@ template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped = formalInfo.permissions.incl(formalMode) formalInfo.id = (rawInfo.st_dev, rawInfo.st_ino) formalInfo.size = rawInfo.st_size - formalInfo.linkCount = rawInfo.st_Nlink + formalInfo.linkCount = rawInfo.st_Nlink.BiggestInt formalInfo.lastAccessTime = rawInfo.st_atime formalInfo.lastWriteTime = rawInfo.st_mtime formalInfo.creationTime = rawInfo.st_ctime diff --git a/lib/pure/ospaths.nim b/lib/pure/ospaths.nim index 71991e35a..7720fb2a6 100644 --- a/lib/pure/ospaths.nim +++ b/lib/pure/ospaths.nim @@ -569,7 +569,7 @@ when declared(getEnv) or defined(nimscript): ## ``["exe", "cmd", "bat"]``, on Posix ``[""]``. proc findExe*(exe: string, followSymlinks: bool = true; - extensions=ExeExts): string {. + extensions: openarray[string]=ExeExts): string {. tags: [ReadDirEffect, ReadEnvEffect, ReadIOEffect].} = ## Searches for `exe` in the current working directory and then ## in directories listed in the ``PATH`` environment variable. diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 0f37f8fe0..c94a65a63 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -209,9 +209,16 @@ proc waitForExit*(p: Process, timeout: int = -1): int {.rtl, ## ## **Warning**: Be careful when using waitForExit for processes created without ## poParentStreams because they may fill output buffers, causing deadlock. + ## + ## On posix, if the process has exited because of a signal, 128 + signal + ## number will be returned. + proc peekExitCode*(p: Process): int {.tags: [].} ## return -1 if the process is still running. Otherwise the process' exit code + ## + ## On posix, if the process has exited because of a signal, 128 + signal + ## number will be returned. proc inputStream*(p: Process): Stream {.rtl, extern: "nosp$1", tags: [].} ## returns ``p``'s input stream for writing to. @@ -328,7 +335,8 @@ proc execProcesses*(cmds: openArray[string], if afterRunEvent != nil: afterRunEvent(i, p) close(p) -proc select*(readfds: var seq[Process], timeout = 500): int {.benign.} +proc select*(readfds: var seq[Process], timeout = 500): int + {.benign, deprecated.} ## `select` with a sensible Nim interface. `timeout` is in milliseconds. ## Specify -1 for no timeout. Returns the number of processes that are ## ready to read from. The processes that are ready to be read from are @@ -336,6 +344,9 @@ proc select*(readfds: var seq[Process], timeout = 500): int {.benign.} ## ## **Warning**: This function may give unexpected or completely wrong ## results on Windows. + ## + ## **Deprecated since version 0.17.0**: This procedure isn't cross-platform + ## and so should not be used in newly written code. when not defined(useNimRtl): proc execProcess(command: string, @@ -679,6 +690,16 @@ elif not defined(useNimRtl): readIdx = 0 writeIdx = 1 + proc isExitStatus(status: cint): bool = + WIFEXITED(status) or WIFSIGNALED(status) + + proc exitStatus(status: cint): cint = + if WIFSIGNALED(status): + # like the shell! + 128 + WTERMSIG(status) + else: + WEXITSTATUS(status) + proc envToCStringArray(t: StringTableRef): cstringArray = result = cast[cstringArray](alloc0((t.len + 1) * sizeof(cstring))) var i = 0 @@ -967,7 +988,7 @@ elif not defined(useNimRtl): var status : cint = 1 ret = waitpid(p.id, status, WNOHANG) if ret == int(p.id): - if WIFEXITED(status): + if isExitStatus(status): p.exitStatus = status return false else: @@ -990,7 +1011,9 @@ elif not defined(useNimRtl): import kqueue, times proc waitForExit(p: Process, timeout: int = -1): int = - if p.exitStatus != -3: return((p.exitStatus and 0xFF00) shr 8) + if p.exitStatus != -3: + return exitStatus(p.exitStatus) + if timeout == -1: var status : cint = 1 if waitpid(p.id, status, 0) < 0: @@ -1041,7 +1064,7 @@ elif not defined(useNimRtl): finally: discard posix.close(kqFD) - result = ((p.exitStatus and 0xFF00) shr 8) + result = exitStatus(p.exitStatus) else: import times @@ -1077,7 +1100,9 @@ elif not defined(useNimRtl): # ``waitPid`` fails if the process is not running anymore. But then # ``running`` probably set ``p.exitStatus`` for us. Since ``p.exitStatus`` is # initialized with -3, wrong success exit codes are prevented. - if p.exitStatus != -3: return((p.exitStatus and 0xFF00) shr 8) + if p.exitStatus != -3: + return exitStatus(p.exitStatus) + if timeout == -1: var status : cint = 1 if waitpid(p.id, status, 0) < 0: @@ -1151,17 +1176,19 @@ elif not defined(useNimRtl): if sigprocmask(SIG_UNBLOCK, nmask, omask) == -1: raiseOSError(osLastError()) - result = ((p.exitStatus and 0xFF00) shr 8) + result = exitStatus(p.exitStatus) proc peekExitCode(p: Process): int = var status = cint(0) result = -1 - if p.exitStatus != -3: return((p.exitStatus and 0xFF00) shr 8) + if p.exitStatus != -3: + return exitStatus(p.exitStatus) + var ret = waitpid(p.id, status, WNOHANG) if ret > 0: - if WIFEXITED(status): + if isExitStatus(status): p.exitStatus = status - result = (status and 0xFF00) shr 8 + result = exitStatus(status) proc createStream(stream: var Stream, handle: var FileHandle, fileMode: FileMode) = @@ -1189,7 +1216,8 @@ elif not defined(useNimRtl): proc execCmd(command: string): int = when defined(linux): - result = csystem(command) shr 8 + let tmp = csystem(command) + result = if tmp == -1: tmp else: exitStatus(tmp) else: result = csystem(command) diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index 8d53a0360..b78e8d000 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -201,7 +201,7 @@ proc parseWhile*(s: string, token: var string, validChars: set[char], proc captureBetween*(s: string, first: char, second = '\0', start = 0): string = ## Finds the first occurrence of ``first``, then returns everything from there - ## up to ``second``(if ``second`` is '\0', then ``first`` is used). + ## up to ``second`` (if ``second`` is '\0', then ``first`` is used). var i = skipUntil(s, first, start)+1+start result = "" discard s.parseUntil(result, if second == '\0': first else: second, i) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 9383675f4..458c22f3a 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -1881,6 +1881,8 @@ proc formatFloat*(f: float, format: FloatFormatMode = ffDefault, ## of significant digits to be printed. ## `precision`'s default value is the maximum number of meaningful digits ## after the decimal point for Nim's ``float`` type. + ## + ## If ``precision == 0``, it tries to format it nicely. result = formatBiggestFloat(f, format, precision, decimalSep) proc trimZeros*(x: var string) {.noSideEffect.} = diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 1b088c0ac..bad003a3e 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -47,15 +47,26 @@ type dMon, dTue, dWed, dThu, dFri, dSat, dSun when defined(posix) and not defined(JS): - type - TimeImpl {.importc: "time_t", header: "<time.h>".} = int - Time* = distinct TimeImpl ## distinct type that represents a time - ## measured as number of seconds since the epoch + when defined(linux) and defined(amd64): + type + TimeImpl {.importc: "time_t", header: "<time.h>".} = clong + Time* = distinct TimeImpl ## distinct type that represents a time + ## measured as number of seconds since the epoch + + Timeval {.importc: "struct timeval", + header: "<sys/select.h>".} = object ## struct timeval + tv_sec: clong ## Seconds. + tv_usec: clong ## Microseconds. + else: + type + TimeImpl {.importc: "time_t", header: "<time.h>".} = int + Time* = distinct TimeImpl ## distinct type that represents a time + ## measured as number of seconds since the epoch - Timeval {.importc: "struct timeval", - header: "<sys/select.h>".} = object ## struct timeval - tv_sec: int ## Seconds. - tv_usec: int ## Microseconds. + Timeval {.importc: "struct timeval", + header: "<sys/select.h>".} = object ## struct timeval + tv_sec: int ## Seconds. + tv_usec: int ## Microseconds. # we cannot import posix.nim here, because posix.nim depends on times.nim. # Ok, we could, but I don't want circular dependencies. @@ -1103,7 +1114,7 @@ when not defined(JS): when defined(freebsd) or defined(netbsd) or defined(openbsd) or defined(macosx): type - StructTM {.importc: "struct tm", final.} = object + StructTM {.importc: "struct tm".} = object second {.importc: "tm_sec".}, minute {.importc: "tm_min".}, hour {.importc: "tm_hour".}, @@ -1116,7 +1127,7 @@ when not defined(JS): gmtoff {.importc: "tm_gmtoff".}: clong else: type - StructTM {.importc: "struct tm", final.} = object + StructTM {.importc: "struct tm".} = object second {.importc: "tm_sec".}, minute {.importc: "tm_min".}, hour {.importc: "tm_hour".}, @@ -1126,6 +1137,9 @@ when not defined(JS): weekday {.importc: "tm_wday".}, yearday {.importc: "tm_yday".}, isdst {.importc: "tm_isdst".}: cint + when defined(linux) and defined(amd64): + gmtoff {.importc: "tm_gmtoff".}: clong + zone {.importc: "tm_zone".}: cstring type TimeInfoPtr = ptr StructTM Clock {.importc: "clock_t".} = distinct int diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index ba745cfd3..c7e0ed1da 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -50,6 +50,7 @@ proc add*(url: var Url, a: Url) {.deprecated.} = proc parseAuthority(authority: string, result: var Uri) = var i = 0 var inPort = false + var inIPv6 = false while true: case authority[i] of '@': @@ -59,7 +60,14 @@ proc parseAuthority(authority: string, result: var Uri) = result.hostname.setLen(0) inPort = false of ':': - inPort = true + if inIPv6: + result.hostname.add(authority[i]) + else: + inPort = true + of '[': + inIPv6 = true + of ']': + inIPv6 = false of '\0': break else: if inPort: @@ -346,6 +354,17 @@ when isMainModule: doAssert($test == str) block: + # IPv6 address + let str = "foo://[::1]:1234/bar?baz=true&qux#quux" + let uri = parseUri(str) + doAssert uri.scheme == "foo" + doAssert uri.hostname == "::1" + doAssert uri.port == "1234" + doAssert uri.path == "/bar" + doAssert uri.query == "baz=true&qux" + doAssert uri.anchor == "quux" + + block: let str = "urn:example:animal:ferret:nose" let test = parseUri(str) doAssert test.scheme == "urn" diff --git a/lib/system.nim b/lib/system.nim index 82d3bb7f7..9b41253cc 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2016,6 +2016,12 @@ proc min*(x, y: float): float {.magic: "MinF64", noSideEffect.} = if x <= y: x else: y proc max*(x, y: float): float {.magic: "MaxF64", noSideEffect.} = if y <= x: x else: y + +proc min*[T](x, y: T): T = + if x <= y: x else: y + +proc max*[T](x, y: T): T = + if y <= x: x else: y {.pop.} proc clamp*[T](x, a, b: T): T = diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index 52065531b..b2f6d314f 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -26,8 +26,14 @@ proc c_memset(p: pointer, value: cint, size: csize): pointer {. proc c_strcmp(a, b: cstring): cint {. importc: "strcmp", header: "<string.h>", noSideEffect.} -type - C_JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>".} = object +when defined(linux) and defined(amd64): + type + C_JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>", bycopy.} = object + abi: array[200 div sizeof(clong), clong] +else: + type + C_JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>".} = object + when defined(windows): const diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index 3a43729dc..885b01621 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -165,8 +165,22 @@ when someGcc and hasThreadSupport: template fence*() = atomicThreadFence(ATOMIC_SEQ_CST) elif defined(vcc) and hasThreadSupport: - proc addAndFetch*(p: ptr int, val: int): int {. - importc: "_InterlockedExchangeAdd", header: "<intrin.h>".} + when defined(cpp): + when sizeof(int) == 8: + proc addAndFetch*(p: ptr int, val: int): int {. + importcpp: "_InterlockedExchangeAdd64(static_cast<NI volatile *>(#), #)", + header: "<intrin.h>".} + else: + proc addAndFetch*(p: ptr int, val: int): int {. + importcpp: "_InterlockedExchangeAdd(static_cast<NI volatile *>(#), #)", + header: "<intrin.h>".} + else: + when sizeof(int) == 8: + proc addAndFetch*(p: ptr int, val: int): int {. + importc: "_InterlockedExchangeAdd64", header: "<intrin.h>".} + else: + proc addAndFetch*(p: ptr int, val: int): int {. + importc: "_InterlockedExchangeAdd", header: "<intrin.h>".} proc fence*() {.importc: "_ReadWriteBarrier", header: "<intrin.h>".} @@ -180,6 +194,7 @@ proc atomicInc*(memLoc: var int, x: int = 1): int = result = atomic_add_fetch(memLoc.addr, x, ATOMIC_RELAXED) elif defined(vcc) and hasThreadSupport: result = addAndFetch(memLoc.addr, x) + inc(result, x) else: inc(memLoc, x) result = memLoc @@ -192,6 +207,7 @@ proc atomicDec*(memLoc: var int, x: int = 1): int = result = atomic_add_fetch(memLoc.addr, -x, ATOMIC_RELAXED) elif defined(vcc) and hasThreadSupport: result = addAndFetch(memLoc.addr, -x) + dec(result, x) else: dec(memLoc, x) result = memLoc diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 8ed1fbb38..55f283d2d 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -38,20 +38,29 @@ proc chckRange(i, a, b: int): int {.inline, compilerproc, benign.} proc chckRangeF(x, a, b: float): float {.inline, compilerproc, benign.} proc chckNil(p: pointer) {.noinline, compilerproc, benign.} +type + GcFrame = ptr GcFrameHeader + GcFrameHeader {.compilerproc.} = object + len: int + prev: ptr GcFrameHeader + var framePtr {.threadvar.}: PFrame excHandler {.threadvar.}: PSafePoint # list of exception handlers # a global variable for the root of all try blocks currException {.threadvar.}: ref Exception + gcFramePtr {.threadvar.}: GcFrame type - FrameState = tuple[framePtr: PFrame, excHandler: PSafePoint, currException: ref Exception] + FrameState = tuple[gcFramePtr: GcFrame, framePtr: PFrame, + excHandler: PSafePoint, currException: ref Exception] proc getFrameState*(): FrameState {.compilerRtl, inl.} = - return (framePtr, excHandler, currException) + return (gcFramePtr, framePtr, excHandler, currException) proc setFrameState*(state: FrameState) {.compilerRtl, inl.} = + gcFramePtr = state.gcFramePtr framePtr = state.framePtr excHandler = state.excHandler currException = state.currException @@ -64,6 +73,14 @@ proc popFrame {.compilerRtl, inl.} = proc setFrame*(s: PFrame) {.compilerRtl, inl.} = framePtr = s +proc getGcFrame*(): GcFrame {.compilerRtl, inl.} = gcFramePtr +proc popGcFrame*() {.compilerRtl, inl.} = gcFramePtr = gcFramePtr.prev +proc setGcFrame*(s: GcFrame) {.compilerRtl, inl.} = gcFramePtr = s +proc pushGcFrame*(s: GcFrame) {.compilerRtl, inl.} = + s.prev = gcFramePtr + zeroMem(cast[pointer](cast[int](s)+%sizeof(GcFrameHeader)), s.len*sizeof(pointer)) + gcFramePtr = s + proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} = s.hasRaiseAction = false s.prev = excHandler @@ -282,8 +299,13 @@ proc raiseExceptionAux(e: ref Exception) = proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} = if e.name.isNil: e.name = ename when hasSomeStackTrace: - e.trace = "" - rawWriteStackTrace(e.trace) + if e.trace.isNil: + e.trace = "" + rawWriteStackTrace(e.trace) + elif framePtr != nil: + e.trace.add "[[reraised from:\n" + auxWriteStackTrace(framePtr, e.trace) + e.trace.add "]]\n" raiseExceptionAux(e) proc reraiseException() {.compilerRtl.} = diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 9ef4a02f2..8a81a550a 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -172,7 +172,7 @@ proc raiseIndexError() {.compilerproc, noreturn.} = proc raiseFieldError(f: string) {.compilerproc, noreturn.} = raise newException(FieldError, f & " is not accessible") -proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} = +proc setConstr() {.varargs, asmNoStackFrame, compilerproc.} = when defined(nimphp): asm """ $args = func_get_args(); diff --git a/lib/system/syslocks.nim b/lib/system/syslocks.nim index 9d056611f..f61b887ad 100644 --- a/lib/system/syslocks.nim +++ b/lib/system/syslocks.nim @@ -99,19 +99,82 @@ elif defined(genode): else: type - SysLock {.importc: "pthread_mutex_t", pure, final, + SysLockObj {.importc: "pthread_mutex_t", pure, final, header: """#include <sys/types.h> #include <pthread.h>""".} = object + when defined(linux) and defined(amd64): + abi: array[40 div sizeof(clong), clong] + SysLockAttr {.importc: "pthread_mutexattr_t", pure, final header: """#include <sys/types.h> #include <pthread.h>""".} = object - SysCond {.importc: "pthread_cond_t", pure, final, + when defined(linux) and defined(amd64): + abi: array[4 div sizeof(cint), cint] # actually a cint + + SysCondObj {.importc: "pthread_cond_t", pure, final, header: """#include <sys/types.h> #include <pthread.h>""".} = object + when defined(linux) and defined(amd64): + abi: array[48 div sizeof(clonglong), clonglong] + SysLockType = distinct cint - proc initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) {. + proc initSysLockAux(L: var SysLockObj, attr: ptr SysLockAttr) {. importc: "pthread_mutex_init", header: "<pthread.h>", noSideEffect.} + proc deinitSysAux(L: var SysLockObj) {.noSideEffect, + importc: "pthread_mutex_destroy", header: "<pthread.h>".} + + proc acquireSysAux(L: var SysLockObj) {.noSideEffect, + importc: "pthread_mutex_lock", header: "<pthread.h>".} + proc tryAcquireSysAux(L: var SysLockObj): cint {.noSideEffect, + importc: "pthread_mutex_trylock", header: "<pthread.h>".} + + proc releaseSysAux(L: var SysLockObj) {.noSideEffect, + importc: "pthread_mutex_unlock", header: "<pthread.h>".} + + when defined(ios): + # iOS will behave badly if sync primitives are moved in memory. In order + # to prevent this once and for all, we're doing an extra malloc when + # initializing the primitive. + type + SysLock = ptr SysLockObj + SysCond = ptr SysCondObj + + when not declared(c_malloc): + proc c_malloc(size: csize): pointer {. + importc: "malloc", header: "<stdlib.h>".} + proc c_free(p: pointer) {. + importc: "free", header: "<stdlib.h>".} + + proc initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) = + L = cast[SysLock](c_malloc(sizeof(SysLockObj))) + initSysLockAux(L[], attr) + + proc deinitSys(L: var SysLock) = + deinitSysAux(L[]) + c_free(L) + + template acquireSys(L: var SysLock) = + acquireSysAux(L[]) + template tryAcquireSys(L: var SysLock): bool = + tryAcquireSysAux(L[]) == 0'i32 + template releaseSys(L: var SysLock) = + releaseSysAux(L[]) + else: + type + SysLock = SysLockObj + SysCond = SysCondObj + + template initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) = + initSysLockAux(L, attr) + template deinitSys(L: var SysLock) = + deinitSysAux(L) + template acquireSys(L: var SysLock) = + acquireSysAux(L) + template tryAcquireSys(L: var SysLock): bool = + tryAcquireSysAux(L) == 0'i32 + template releaseSys(L: var SysLock) = + releaseSysAux(L) when insideRLocksModule: proc SysLockType_Reentrant: SysLockType = @@ -121,27 +184,39 @@ else: proc setSysLockType(a: var SysLockAttr, t: SysLockType) {. importc: "pthread_mutexattr_settype", header: "<pthread.h>", noSideEffect.} - proc acquireSys(L: var SysLock) {.noSideEffect, - importc: "pthread_mutex_lock", header: "<pthread.h>".} - proc tryAcquireSysAux(L: var SysLock): cint {.noSideEffect, - importc: "pthread_mutex_trylock", header: "<pthread.h>".} - - proc tryAcquireSys(L: var SysLock): bool {.inline.} = - result = tryAcquireSysAux(L) == 0'i32 - - proc releaseSys(L: var SysLock) {.noSideEffect, - importc: "pthread_mutex_unlock", header: "<pthread.h>".} - proc deinitSys(L: var SysLock) {.noSideEffect, - importc: "pthread_mutex_destroy", header: "<pthread.h>".} - - when not insideRLocksModule: - proc initSysCond(cond: var SysCond, cond_attr: pointer = nil) {. + else: + proc initSysCondAux(cond: var SysCondObj, cond_attr: pointer) {. importc: "pthread_cond_init", header: "<pthread.h>", noSideEffect.} - proc waitSysCond(cond: var SysCond, lock: var SysLock) {. + proc deinitSysCondAux(cond: var SysCondObj) {.noSideEffect, + importc: "pthread_cond_destroy", header: "<pthread.h>".} + + proc waitSysCondAux(cond: var SysCondObj, lock: var SysLockObj) {. importc: "pthread_cond_wait", header: "<pthread.h>", noSideEffect.} - proc signalSysCond(cond: var SysCond) {. + proc signalSysCondAux(cond: var SysCondObj) {. importc: "pthread_cond_signal", header: "<pthread.h>", noSideEffect.} - proc deinitSysCond(cond: var SysCond) {.noSideEffect, - importc: "pthread_cond_destroy", header: "<pthread.h>".} + + when defined(ios): + proc initSysCond(cond: var SysCond, cond_attr: pointer = nil) = + cond = cast[SysCond](c_malloc(sizeof(SysCondObj))) + initSysCondAux(cond[], cond_attr) + + proc deinitSysCond(cond: var SysCond) = + deinitSysCondAux(cond[]) + c_free(cond) + + template waitSysCond(cond: var SysCond, lock: var SysLock) = + waitSysCondAux(cond[], lock[]) + template signalSysCond(cond: var SysCond) = + signalSysCondAux(cond[]) + else: + template initSysCond(cond: var SysCond, cond_attr: pointer = nil) = + initSysCondAux(cond, cond_attr) + template deinitSysCond(cond: var SysCond) = + deinitSysCondAux(cond) + + template waitSysCond(cond: var SysCond, lock: var SysLock) = + waitSysCondAux(cond, lock) + template signalSysCond(cond: var SysCond) = + signalSysCondAux(cond) {.pop.} diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 7743fffff..d1012e9c5 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -177,18 +177,28 @@ else: else: type Time = int + when defined(linux) and defined(amd64): + type + SysThread* {.importc: "pthread_t", + header: "<sys/types.h>" .} = distinct culong + Pthread_attr {.importc: "pthread_attr_t", + header: "<sys/types.h>".} = object + abi: array[56 div sizeof(clong), clong] + ThreadVarSlot {.importc: "pthread_key_t", + header: "<sys/types.h>".} = distinct cuint + else: + type + SysThread* {.importc: "pthread_t", header: "<sys/types.h>".} = object + Pthread_attr {.importc: "pthread_attr_t", + header: "<sys/types.h>".} = object + ThreadVarSlot {.importc: "pthread_key_t", + header: "<sys/types.h>".} = object type - SysThread* {.importc: "pthread_t", header: "<sys/types.h>", - final, pure.} = object - Pthread_attr {.importc: "pthread_attr_t", - header: "<sys/types.h>", final, pure.} = object - - Timespec {.importc: "struct timespec", - header: "<time.h>", final, pure.} = object + Timespec {.importc: "struct timespec", header: "<time.h>".} = object tv_sec: Time tv_nsec: clong {.deprecated: [TSysThread: SysThread, Tpthread_attr: PThreadAttr, - Ttimespec: Timespec].} + Ttimespec: Timespec, TThreadVarSlot: ThreadVarSlot].} proc pthread_attr_init(a1: var PthreadAttr) {. importc, header: pthreadh.} @@ -205,11 +215,6 @@ else: proc pthread_cancel(a1: SysThread): cint {. importc: "pthread_cancel", header: pthreadh.} - type - ThreadVarSlot {.importc: "pthread_key_t", pure, final, - header: "<sys/types.h>".} = object - {.deprecated: [TThreadVarSlot: ThreadVarSlot].} - proc pthread_getspecific(a1: ThreadVarSlot): pointer {. importc: "pthread_getspecific", header: pthreadh.} proc pthread_key_create(a1: ptr ThreadVarSlot, @@ -234,6 +239,9 @@ else: importc: "pthread_attr_setstack", header: pthreadh.} type CpuSet {.importc: "cpu_set_t", header: schedh.} = object + when defined(linux) and defined(amd64): + abi: array[1024 div (8 * sizeof(culong)), culong] + proc cpusetZero(s: var CpuSet) {.importc: "CPU_ZERO", header: schedh.} proc cpusetIncl(cpu: cint; s: var CpuSet) {. importc: "CPU_SET", header: schedh.} diff --git a/lib/upcoming/asyncdispatch.nim b/lib/upcoming/asyncdispatch.nim index feee87bae..1623d8375 100644 --- a/lib/upcoming/asyncdispatch.nim +++ b/lib/upcoming/asyncdispatch.nim @@ -9,7 +9,7 @@ include "system/inclrtl" -import os, oids, tables, strutils, times, heapqueue, lists +import os, tables, strutils, times, heapqueue, lists, options import nativesockets, net, deques @@ -219,6 +219,11 @@ when defined(windows) or defined(nimdoc): if gDisp.isNil: gDisp = newDispatcher() result = gDisp + proc setGlobalDispatcher*(disp: PDispatcher) = + if not gDisp.isNil: + assert gDisp.callbacks.len == 0 + gDisp = disp + proc register*(fd: AsyncFD) = ## Registers ``fd`` with the dispatcher. let p = getGlobalDispatcher() @@ -325,68 +330,6 @@ when defined(windows) or defined(nimdoc): getAcceptExSockAddrs = cast[WSAPROC_GETACCEPTEXSOCKADDRS](fun) close(dummySock) - proc connect*(socket: AsyncFD, address: string, port: Port, - domain = nativesockets.AF_INET): Future[void] = - ## Connects ``socket`` to server at ``address:port``. - ## - ## Returns a ``Future`` which will complete when the connection succeeds - ## or an error occurs. - verifyPresence(socket) - var retFuture = newFuture[void]("connect") - # Apparently ``ConnectEx`` expects the socket to be initially bound: - var saddr: Sockaddr_in - saddr.sin_family = int16(toInt(domain)) - saddr.sin_port = 0 - saddr.sin_addr.s_addr = INADDR_ANY - if bindAddr(socket.SocketHandle, cast[ptr SockAddr](addr(saddr)), - sizeof(saddr).SockLen) < 0'i32: - raiseOSError(osLastError()) - - var aiList = getAddrInfo(address, port, domain) - var success = false - var lastError: OSErrorCode - var it = aiList - while it != nil: - # "the OVERLAPPED structure must remain valid until the I/O completes" - # http://blogs.msdn.com/b/oldnewthing/archive/2011/02/02/10123392.aspx - var ol = PCustomOverlapped() - GC_ref(ol) - ol.data = CompletionData(fd: socket, cb: - proc (fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = - if not retFuture.finished: - if errcode == OSErrorCode(-1): - retFuture.complete() - else: - retFuture.fail(newException(OSError, osErrorMsg(errcode))) - ) - - var ret = connectEx(socket.SocketHandle, it.ai_addr, - sizeof(Sockaddr_in).cint, nil, 0, nil, - cast[POVERLAPPED](ol)) - if ret: - # Request to connect completed immediately. - success = true - retFuture.complete() - # We don't deallocate ``ol`` here because even though this completed - # immediately poll will still be notified about its completion and it will - # free ``ol``. - break - else: - lastError = osLastError() - if lastError.int32 == ERROR_IO_PENDING: - # In this case ``ol`` will be deallocated in ``poll``. - success = true - break - else: - GC_unref(ol) - success = false - it = it.ai_next - - freeAddrInfo(aiList) - if not success: - retFuture.fail(newException(OSError, osErrorMsg(lastError))) - return retFuture - proc recv*(socket: AsyncFD, size: int, flags = {SocketFlag.SafeDisconn}): Future[string] = ## Reads **up to** ``size`` bytes from ``socket``. Returned future will @@ -739,8 +682,8 @@ when defined(windows) or defined(nimdoc): var lpOutputBuf = newString(lpOutputLen) var dwBytesReceived: Dword let dwReceiveDataLength = 0.Dword # We don't want any data to be read. - let dwLocalAddressLength = Dword(sizeof(Sockaddr_in) + 16) - let dwRemoteAddressLength = Dword(sizeof(Sockaddr_in) + 16) + let dwLocalAddressLength = Dword(sizeof(Sockaddr_in6) + 16) + let dwRemoteAddressLength = Dword(sizeof(Sockaddr_in6) + 16) template failAccept(errcode) = if flags.isDisconnectionError(errcode): @@ -770,12 +713,14 @@ when defined(windows) or defined(nimdoc): dwLocalAddressLength, dwRemoteAddressLength, addr localSockaddr, addr localLen, addr remoteSockaddr, addr remoteLen) - register(clientSock.AsyncFD) - # TODO: IPv6. Check ``sa_family``. http://stackoverflow.com/a/9212542/492186 - retFuture.complete( - (address: $inet_ntoa(cast[ptr Sockaddr_in](remoteSockAddr).sin_addr), - client: clientSock.AsyncFD) - ) + try: + let address = getAddrString(remoteSockAddr) + register(clientSock.AsyncFD) + retFuture.complete((address: address, client: clientSock.AsyncFD)) + except: + # getAddrString may raise + clientSock.close() + retFuture.fail(getCurrentException()) var ol = PCustomOverlapped() GC_ref(ol) @@ -808,20 +753,6 @@ when defined(windows) or defined(nimdoc): return retFuture - proc newAsyncNativeSocket*(domain, sockType, protocol: cint): AsyncFD = - ## Creates a new socket and registers it with the dispatcher implicitly. - result = newNativeSocket(domain, sockType, protocol).AsyncFD - result.SocketHandle.setBlocking(false) - register(result) - - proc newAsyncNativeSocket*(domain: Domain = nativesockets.AF_INET, - sockType: SockType = SOCK_STREAM, - protocol: Protocol = IPPROTO_TCP): AsyncFD = - ## Creates a new socket and registers it with the dispatcher implicitly. - result = newNativeSocket(domain, sockType, protocol).AsyncFD - result.SocketHandle.setBlocking(false) - register(result) - proc closeSocket*(socket: AsyncFD) = ## Closes a socket and ensures that it is unregistered. socket.SocketHandle.close() @@ -1154,28 +1085,16 @@ else: if gDisp.isNil: gDisp = newDispatcher() result = gDisp + proc setGlobalDispatcher*(disp: PDispatcher) = + if not gDisp.isNil: + assert gDisp.callbacks.len == 0 + gDisp = disp + proc register*(fd: AsyncFD) = let p = getGlobalDispatcher() var data = newAsyncData() p.selector.registerHandle(fd.SocketHandle, {}, data) - proc newAsyncNativeSocket*(domain: cint, sockType: cint, - protocol: cint): AsyncFD = - result = newNativeSocket(domain, sockType, protocol).AsyncFD - result.SocketHandle.setBlocking(false) - when defined(macosx): - result.SocketHandle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1) - register(result) - - proc newAsyncNativeSocket*(domain: Domain = AF_INET, - sockType: SockType = SOCK_STREAM, - protocol: Protocol = IPPROTO_TCP): AsyncFD = - result = newNativeSocket(domain, sockType, protocol).AsyncFD - result.SocketHandle.setBlocking(false) - when defined(macosx): - result.SocketHandle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1) - register(result) - proc closeSocket*(sock: AsyncFD) = let disp = getGlobalDispatcher() disp.selector.unregister(sock.SocketHandle) @@ -1331,50 +1250,6 @@ else: # Callback queue processing processPendingCallbacks(p) - proc connect*(socket: AsyncFD, address: string, port: Port, - domain = AF_INET): Future[void] = - var retFuture = newFuture[void]("connect") - - proc cb(fd: AsyncFD): bool = - var ret = SocketHandle(fd).getSockOptInt(cint(SOL_SOCKET), cint(SO_ERROR)) - if ret == 0: - # We have connected. - retFuture.complete() - return true - elif ret == EINTR: - # interrupted, keep waiting - return false - else: - retFuture.fail(newException(OSError, osErrorMsg(OSErrorCode(ret)))) - return true - - assert getSockDomain(socket.SocketHandle) == domain - var aiList = getAddrInfo(address, port, domain) - var success = false - var lastError: OSErrorCode - var it = aiList - while it != nil: - var ret = connect(socket.SocketHandle, it.ai_addr, it.ai_addrlen.Socklen) - if ret == 0: - # Request to connect completed immediately. - success = true - retFuture.complete() - break - else: - lastError = osLastError() - if lastError.int32 == EINTR or lastError.int32 == EINPROGRESS: - success = true - addWrite(socket, cb) - break - else: - success = false - it = it.ai_next - - freeAddrInfo(aiList) - if not success: - retFuture.fail(newException(OSError, osErrorMsg(lastError))) - return retFuture - proc recv*(socket: AsyncFD, size: int, flags = {SocketFlag.SafeDisconn}): Future[string] = var retFuture = newFuture[string]("recv") @@ -1568,9 +1443,14 @@ else: else: retFuture.fail(newException(OSError, osErrorMsg(lastError))) else: - register(client.AsyncFD) - retFuture.complete((getAddrString(cast[ptr SockAddr](addr sockAddress)), - client.AsyncFD)) + try: + let address = getAddrString(cast[ptr SockAddr](addr sockAddress)) + register(client.AsyncFD) + retFuture.complete((address, client.AsyncFD)) + except: + # getAddrString may raise + client.close() + retFuture.fail(getCurrentException()) addRead(socket, cb) return retFuture @@ -1623,6 +1503,9 @@ else: data.readList.add(cb) p.selector.registerEvent(SelectEvent(ev), data) +# Common procedures between current and upcoming asyncdispatch +include includes.asynccommon + proc sleepAsync*(ms: int): Future[void] = ## Suspends the execution of the current async procedure for the next ## ``ms`` milliseconds. diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 1f8dc9ad6..164499543 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -495,7 +495,7 @@ type ai_family*: cint ## Address family of socket. ai_socktype*: cint ## Socket type. ai_protocol*: cint ## Protocol of socket. - ai_addrlen*: int ## Length of socket address. + ai_addrlen*: csize ## Length of socket address. ai_canonname*: cstring ## Canonical name of service location. ai_addr*: ptr SockAddr ## Socket address of socket. ai_next*: ptr AddrInfo ## Pointer to next in list. @@ -803,6 +803,7 @@ const SIO_GET_EXTENSION_FUNCTION_POINTER* = WSAIORW(IOC_WS2,6).DWORD SO_UPDATE_ACCEPT_CONTEXT* = 0x700B AI_V4MAPPED* = 0x0008 + AF_UNSPEC* = 0 AF_INET* = 2 AF_INET6* = 23 |