diff options
Diffstat (limited to 'lib')
-rwxr-xr-x | lib/posix/posix.nim | 283 | ||||
-rwxr-xr-x | lib/pure/browsers.nim | 43 | ||||
-rwxr-xr-x | lib/pure/cgi.nim | 86 | ||||
-rwxr-xr-x | lib/pure/os.nim | 2 | ||||
-rwxr-xr-x | lib/pure/sockets.nim | 381 | ||||
-rwxr-xr-x | lib/pure/strutils.nim | 6 | ||||
-rwxr-xr-x | lib/pure/times.nim | 2 | ||||
-rwxr-xr-x | lib/system.nim | 14 | ||||
-rwxr-xr-x | lib/windows/winlean.nim | 146 |
9 files changed, 719 insertions, 244 deletions
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index ddeaec664..005b6dbe0 100755 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -1,7 +1,7 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -122,7 +122,8 @@ type Ticonv* {.importc: "iconv_t", header: "<iconv.h>", final, pure.} = object ## Identifies the conversion from one codeset to another. - Tlconv* {.importc: "struct lconv", header: "<locale.h>", final, pure.} = object + Tlconv* {.importc: "struct lconv", header: "<locale.h>", final, + pure.} = object currency_symbol*: cstring decimal_point*: cstring frac_digits*: char @@ -195,7 +196,8 @@ type Tpthread_mutexattr* {.importc: "pthread_mutexattr_t", header: "<sys/types.h>".} = int Tpthread_once* {.importc: "pthread_once_t", header: "<sys/types.h>".} = int - Tpthread_rwlock* {.importc: "pthread_rwlock_t", header: "<sys/types.h>".} = int + Tpthread_rwlock* {.importc: "pthread_rwlock_t", + header: "<sys/types.h>".} = int Tpthread_rwlockattr* {.importc: "pthread_rwlockattr_t", header: "<sys/types.h>".} = int Tpthread_spinlock* {.importc: "pthread_spinlock_t", @@ -310,7 +312,7 @@ type sigev_notify*: cint ## Notification type. sigev_signo*: cint ## Signal number. sigev_value*: Tsigval ## Signal value. - sigev_notify_function*: proc (x: TSigval) {.noconv.} ## Notification function. + sigev_notify_function*: proc (x: TSigval) {.noconv.} ## Notification func. sigev_notify_attributes*: ptr Tpthreadattr ## Notification attributes. TsigVal* {.importc: "union sigval", @@ -368,8 +370,8 @@ type Ttimeval* {.importc: "struct timeval", header: "<sys/select.h>", final, pure.} = object ## struct timeval - tv_sec*: ttime ## Seconds. - tv_usec*: tsuseconds ## Microseconds. + tv_sec*: int ## Seconds. + tv_usec*: int ## Microseconds. Tfd_set* {.importc: "struct fd_set", header: "<sys/select.h>", final, pure.} = object Tmcontext* {.importc: "mcontext_t", header: "<ucontext.h>", @@ -595,7 +597,7 @@ var 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]). + ## 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 @@ -1061,27 +1063,42 @@ var 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 + 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_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_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 @@ -1092,8 +1109,10 @@ var 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_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 @@ -1105,8 +1124,10 @@ var 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_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 @@ -1116,9 +1137,11 @@ var 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_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_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 @@ -1127,14 +1150,18 @@ var 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_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_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 @@ -1144,49 +1171,70 @@ var 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_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_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_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_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_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_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_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 @@ -1372,7 +1420,8 @@ var 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. + ## 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 @@ -1385,7 +1434,8 @@ var ## 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.} + 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. @@ -1685,8 +1735,10 @@ proc ntohs*(a1: int16): int16 {.importc, header: "<arpa/inet.h>".} proc inet_addr*(a1: cstring): int32 {.importc, header: "<arpa/inet.h>".} proc inet_ntoa*(a1: int32): cstring {.importc, header: "<arpa/inet.h>".} -proc inet_ntop*(a1: cint, a2: pointer, a3: cstring, a4: int32): cstring {.importc, header: "<arpa/inet.h>".} -proc inet_pton*(a1: cint, a2: cstring, a3: pointer): cint {.importc, header: "<arpa/inet.h>".} +proc inet_ntop*(a1: cint, a2: pointer, a3: cstring, a4: int32): cstring {. + importc, header: "<arpa/inet.h>".} +proc inet_pton*(a1: cint, a2: cstring, a3: pointer): cint {. + importc, header: "<arpa/inet.h>".} var in6addr_any* {.importc, header: "<netinet/in.h>".}: TIn6Addr @@ -1714,13 +1766,17 @@ proc dlsym*(a1: pointer, a2: cstring): pointer {.importc, header: "<dlfcn.h>".} proc creat*(a1: cstring, a2: Tmode): cint {.importc, header: "<fcntl.h>".} proc fcntl*(a1: cint, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".} proc open*(a1: cstring, a2: cint): cint {.varargs, importc, header: "<fcntl.h>".} -proc posix_fadvise*(a1: cint, a2, a3: Toff, a4: cint): cint {.importc, header: "<fcntl.h>".} -proc posix_fallocate*(a1: cint, a2, a3: Toff): cint {.importc, header: "<fcntl.h>".} +proc posix_fadvise*(a1: cint, a2, a3: Toff, a4: cint): cint {. + importc, header: "<fcntl.h>".} +proc posix_fallocate*(a1: cint, a2, a3: Toff): cint {. + importc, header: "<fcntl.h>".} proc feclearexcept*(a1: cint): cint {.importc, header: "<fenv.h>".} -proc fegetexceptflag*(a1: ptr Tfexcept, a2: cint): cint {.importc, header: "<fenv.h>".} +proc fegetexceptflag*(a1: ptr Tfexcept, a2: cint): cint {. + importc, header: "<fenv.h>".} proc feraiseexcept*(a1: cint): cint {.importc, header: "<fenv.h>".} -proc fesetexceptflag*(a1: ptr Tfexcept, a2: cint): cint {.importc, header: "<fenv.h>".} +proc fesetexceptflag*(a1: ptr Tfexcept, a2: cint): cint {. + importc, header: "<fenv.h>".} proc fetestexcept*(a1: cint): cint {.importc, header: "<fenv.h>".} proc fegetround*(): cint {.importc, header: "<fenv.h>".} proc fesetround*(a1: cint): cint {.importc, header: "<fenv.h>".} @@ -1737,7 +1793,8 @@ proc ftw*(a1: cstring, a2: proc (x1: cstring, x2: ptr TStat, x3: cint): cint {.noconv.}, a3: cint): cint {.importc, header: "<ftw.h>".} proc nftw*(a1: cstring, - a2: proc (x1: cstring, x2: ptr TStat, x3: cint, x4: ptr TFTW): cint {.noconv.}, + a2: proc (x1: cstring, x2: ptr TStat, + x3: cint, x4: ptr TFTW): cint {.noconv.}, a3: cint, a4: cint): cint {.importc, header: "<ftw.h>".} @@ -1751,7 +1808,8 @@ proc getgrnam*(a1: cstring): ptr TGroup {.importc, header: "<grp.h>".} proc getgrgid_r*(a1: Tgid, a2: ptr TGroup, a3: cstring, a4: int, a5: ptr ptr TGroup): cint {.importc, header: "<grp.h>".} proc getgrnam_r*(a1: cstring, a2: ptr TGroup, a3: cstring, - a4: int, a5: ptr ptr TGroup): cint {.importc, header: "<grp.h>".} + a4: int, a5: ptr ptr TGroup): cint {. + importc, header: "<grp.h>".} proc getgrent*(): ptr TGroup {.importc, header: "<grp.h>".} proc endgrent*() {.importc, header: "<grp.h>".} proc setgrent*() {.importc, header: "<grp.h>".} @@ -1775,12 +1833,18 @@ proc strfmon*(a1: cstring, a2: int, a3: cstring): int {.varargs, importc, header: "<monetary.h>".} proc mq_close*(a1: Tmqd): cint {.importc, header: "<mqueue.h>".} -proc mq_getattr*(a1: Tmqd, a2: ptr Tmq_attr): cint {.importc, header: "<mqueue.h>".} -proc mq_notify*(a1: Tmqd, a2: ptr Tsigevent): cint {.importc, header: "<mqueue.h>".} -proc mq_open*(a1: cstring, a2: cint): TMqd {.varargs, importc, header: "<mqueue.h>".} -proc mq_receive*(a1: Tmqd, a2: cstring, a3: int, a4: var int): int {.importc, header: "<mqueue.h>".} -proc mq_send*(a1: Tmqd, a2: cstring, a3: int, a4: int): cint {.importc, header: "<mqueue.h>".} -proc mq_setattr*(a1: Tmqd, a2, a3: ptr Tmq_attr): cint {.importc, header: "<mqueue.h>".} +proc mq_getattr*(a1: Tmqd, a2: ptr Tmq_attr): cint {. + importc, header: "<mqueue.h>".} +proc mq_notify*(a1: Tmqd, a2: ptr Tsigevent): cint {. + importc, header: "<mqueue.h>".} +proc mq_open*(a1: cstring, a2: cint): TMqd {. + varargs, importc, header: "<mqueue.h>".} +proc mq_receive*(a1: Tmqd, a2: cstring, a3: int, a4: var int): int {. + importc, header: "<mqueue.h>".} +proc mq_send*(a1: Tmqd, a2: cstring, a3: int, a4: int): cint {. + importc, header: "<mqueue.h>".} +proc mq_setattr*(a1: Tmqd, a2, a3: ptr Tmq_attr): cint {. + importc, header: "<mqueue.h>".} proc mq_timedreceive*(a1: Tmqd, a2: cstring, a3: int, a4: int, a5: ptr TTimespec): int {.importc, header: "<mqueue.h>".} @@ -1801,10 +1865,14 @@ proc setpwent*() {.importc, header: "<pwd.h>".} proc uname*(a1: var Tutsname): cint {.importc, header: "<sys/utsname.h>".} -proc pthread_atfork*(a1, a2, a3: proc {.noconv.}): cint {.importc, header: "<pthread.h>".} -proc pthread_attr_destroy*(a1: ptr Tpthread_attr): cint {.importc, header: "<pthread.h>".} -proc pthread_attr_getdetachstate*(a1: ptr Tpthread_attr, a2: cint): cint {.importc, header: "<pthread.h>".} -proc pthread_attr_getguardsize*(a1: ptr Tpthread_attr, a2: var cint): cint {.importc, header: "<pthread.h>".} +proc pthread_atfork*(a1, a2, a3: proc {.noconv.}): cint {. + importc, header: "<pthread.h>".} +proc pthread_attr_destroy*(a1: ptr Tpthread_attr): cint {. + importc, header: "<pthread.h>".} +proc pthread_attr_getdetachstate*(a1: ptr Tpthread_attr, a2: cint): cint {. + importc, header: "<pthread.h>".} +proc pthread_attr_getguardsize*(a1: ptr Tpthread_attr, a2: var cint): cint {. + importc, header: "<pthread.h>".} proc pthread_attr_getinheritsched*(a1: ptr Tpthread_attr, a2: var cint): cint {.importc, header: "<pthread.h>".} proc pthread_attr_getschedparam*(a1: ptr Tpthread_attr, @@ -1819,30 +1887,48 @@ proc pthread_attr_getstackaddr*(a1: ptr Tpthread_attr, a2: var pointer): cint {.importc, header: "<pthread.h>".} proc pthread_attr_getstacksize*(a1: ptr Tpthread_attr, a2: var int): cint {.importc, header: "<pthread.h>".} -proc pthread_attr_init*(a1: ptr Tpthread_attr): cint {.importc, header: "<pthread.h>".} -proc pthread_attr_setdetachstate*(a1: ptr Tpthread_attr, a2: cint): cint {.importc, header: "<pthread.h>".} -proc pthread_attr_setguardsize*(a1: ptr Tpthread_attr, a2: int): cint {.importc, header: "<pthread.h>".} -proc pthread_attr_setinheritsched*(a1: ptr Tpthread_attr, a2: cint): cint {.importc, header: "<pthread.h>".} +proc pthread_attr_init*(a1: ptr Tpthread_attr): cint {. + importc, header: "<pthread.h>".} +proc pthread_attr_setdetachstate*(a1: ptr Tpthread_attr, a2: cint): cint {. + importc, header: "<pthread.h>".} +proc pthread_attr_setguardsize*(a1: ptr Tpthread_attr, a2: int): cint {. + importc, header: "<pthread.h>".} +proc pthread_attr_setinheritsched*(a1: ptr Tpthread_attr, a2: cint): cint {. + importc, header: "<pthread.h>".} proc pthread_attr_setschedparam*(a1: ptr Tpthread_attr, a2: ptr Tsched_param): cint {.importc, header: "<pthread.h>".} -proc pthread_attr_setschedpolicy*(a1: ptr Tpthread_attr, a2: cint): cint {.importc, header: "<pthread.h>".} -proc pthread_attr_setscope*(a1: ptr Tpthread_attr, a2: cint): cint {.importc, header: "<pthread.h>".} -proc pthread_attr_setstack*(a1: ptr Tpthread_attr, a2: pointer, a3: int): cint {.importc, header: "<pthread.h>".} -proc pthread_attr_setstackaddr*(a1: ptr TPthread_attr, a2: pointer): cint {.importc, header: "<pthread.h>".} -proc pthread_attr_setstacksize*(a1: ptr TPthread_attr, a2: int): cint {.importc, header: "<pthread.h>".} -proc pthread_barrier_destroy*(a1: ptr Tpthread_barrier): cint {.importc, header: "<pthread.h>".} +proc pthread_attr_setschedpolicy*(a1: ptr Tpthread_attr, a2: cint): cint {. + importc, header: "<pthread.h>".} +proc pthread_attr_setscope*(a1: ptr Tpthread_attr, a2: cint): cint {.importc, + header: "<pthread.h>".} +proc pthread_attr_setstack*(a1: ptr Tpthread_attr, a2: pointer, a3: int): cint {. + importc, header: "<pthread.h>".} +proc pthread_attr_setstackaddr*(a1: ptr TPthread_attr, a2: pointer): cint {. + importc, header: "<pthread.h>".} +proc pthread_attr_setstacksize*(a1: ptr TPthread_attr, a2: int): cint {. + importc, header: "<pthread.h>".} +proc pthread_barrier_destroy*(a1: ptr Tpthread_barrier): cint {. + importc, header: "<pthread.h>".} proc pthread_barrier_init*(a1: ptr Tpthread_barrier, - a2: ptr Tpthread_barrierattr, a3: cint): cint {.importc, header: "<pthread.h>".} -proc pthread_barrier_wait*(a1: ptr Tpthread_barrier): cint {.importc, header: "<pthread.h>".} -proc pthread_barrierattr_destroy*(a1: ptr Tpthread_barrierattr): cint {.importc, header: "<pthread.h>".} + a2: ptr Tpthread_barrierattr, a3: cint): cint {. + importc, header: "<pthread.h>".} +proc pthread_barrier_wait*(a1: ptr Tpthread_barrier): cint {. + importc, header: "<pthread.h>".} +proc pthread_barrierattr_destroy*(a1: ptr Tpthread_barrierattr): cint {. + importc, header: "<pthread.h>".} proc pthread_barrierattr_getpshared*( - a1: ptr Tpthread_barrierattr, a2: var cint): cint {.importc, header: "<pthread.h>".} -proc pthread_barrierattr_init*(a1: ptr TPthread_barrierattr): cint {.importc, header: "<pthread.h>".} -proc pthread_barrierattr_setpshared*(a1: ptr TPthread_barrierattr, a2: cint): cint {.importc, header: "<pthread.h>".} + a1: ptr Tpthread_barrierattr, a2: var cint): cint {. + importc, header: "<pthread.h>".} +proc pthread_barrierattr_init*(a1: ptr TPthread_barrierattr): cint {. + importc, header: "<pthread.h>".} +proc pthread_barrierattr_setpshared*(a1: ptr TPthread_barrierattr, + a2: cint): cint {.importc, header: "<pthread.h>".} proc pthread_cancel*(a1: Tpthread): cint {.importc, header: "<pthread.h>".} -proc pthread_cleanup_push*(a1: proc (x: pointer) {.noconv.}, a2: pointer) {.importc, header: "<pthread.h>".} +proc pthread_cleanup_push*(a1: proc (x: pointer) {.noconv.}, a2: pointer) {. + importc, header: "<pthread.h>".} proc pthread_cleanup_pop*(a1: cint) {.importc, header: "<pthread.h>".} -proc pthread_cond_broadcast*(a1: ptr Tpthread_cond): cint {.importc, header: "<pthread.h>".} +proc pthread_cond_broadcast*(a1: ptr Tpthread_cond): cint {. + importc, header: "<pthread.h>".} proc pthread_cond_destroy*(a1: ptr Tpthread_cond): cint {.importc, header: "<pthread.h>".} proc pthread_cond_init*(a1: ptr Tpthread_cond, a2: ptr Tpthread_condattr): cint {.importc, header: "<pthread.h>".} @@ -2167,7 +2253,7 @@ proc tzset*() {.importc, header: "<time.h>".} proc wait*(a1: var cint): tpid {.importc, header: "<sys/wait.h>".} proc waitid*(a1: cint, a2: tid, a3: var Tsiginfo, a4: cint): cint {. importc, header: "<sys/wait.h>".} -proc waitpid*(a1: tpid, a2: var cint, a3: cint): tpid {. +proc waitpid*(a1: tpid, a2: var cint, a3: cint): tpid {. importc, header: "<sys/wait.h>".} proc bsd_signal*(a1: cint, a2: proc (x: pointer) {.noconv.}) {. @@ -2198,11 +2284,13 @@ proc sigprocmask*(a1: cint, a2, a3: var tsigset): cint {. proc sigqueue*(a1: tpid, a2: cint, a3: Tsigval): cint {. importc, header: "<signal.h>".} proc sigrelse*(a1: cint): cint {.importc, header: "<signal.h>".} -proc sigset*(a1: int, a2: proc (x: cint) {.noconv.}) {.importc, header: "<signal.h>".} +proc sigset*(a1: int, a2: proc (x: cint) {.noconv.}) {. + importc, header: "<signal.h>".} proc sigsuspend*(a1: var Tsigset): cint {.importc, header: "<signal.h>".} proc sigtimedwait*(a1: var Tsigset, a2: var tsiginfo, a3: var ttimespec): cint {.importc, header: "<signal.h>".} -proc sigwait*(a1: var Tsigset, a2: var cint): cint {.importc, header: "<signal.h>".} +proc sigwait*(a1: var Tsigset, a2: var cint): cint {. + importc, header: "<signal.h>".} proc sigwaitinfo*(a1: var Tsigset, a2: var tsiginfo): cint {. importc, header: "<signal.h>".} @@ -2210,7 +2298,8 @@ proc sigwaitinfo*(a1: var Tsigset, a2: var tsiginfo): cint {. proc catclose*(a1: Tnl_catd): cint {.importc, header: "<nl_types.h>".} proc catgets*(a1: Tnl_catd, a2, a3: cint, a4: cstring): cstring {. importc, header: "<nl_types.h>".} -proc catopen*(a1: cstring, a2: cint): Tnl_catd {.importc, header: "<nl_types.h>".} +proc catopen*(a1: cstring, a2: cint): Tnl_catd {. + importc, header: "<nl_types.h>".} proc sched_get_priority_max*(a1: cint): cint {.importc, header: "<sched.h>".} proc sched_get_priority_min*(a1: cint): cint {.importc, header: "<sched.h>".} @@ -2233,9 +2322,9 @@ proc FD_ISSET*(a1: cint, a2: var Tfd_set): cint {. proc FD_SET*(a1: cint, a2: var Tfd_set) {.importc, header: "<sys/select.h>".} proc FD_ZERO*(a1: var Tfd_set) {.importc, header: "<sys/select.h>".} -proc pselect*(a1: cint, a2, a3, a4: var Tfd_set, a5: var ttimespec, +proc pselect*(a1: cint, a2, a3, a4: ptr Tfd_set, a5: ptr ttimespec, a6: var Tsigset): cint {.importc, header: "<sys/select.h>".} -proc select*(a1: cint, a2, a3, a4: var Tfd_set, a5: var ttimeval): cint {. +proc select*(a1: cint, a2, a3, a4: ptr Tfd_set, a5: ptr ttimeval): cint {. importc, header: "<sys/select.h>".} when hasSpawnH: diff --git a/lib/pure/browsers.nim b/lib/pure/browsers.nim new file mode 100755 index 000000000..243c07dad --- /dev/null +++ b/lib/pure/browsers.nim @@ -0,0 +1,43 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2010 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module implements a simple proc for opening URLs with the user's +## default browser. + +import strutils + +when defined(windows): + import winlean +else: + import os, osproc + +proc openDefaultBrowser*(url: string) = + ## opens `url` with the user's default browser. This does not block. + ## + ## Under Windows, ``ShellExecute`` is used. Under Mac OS X the ``open`` + ## command is used. Under Unix, it is checked if ``gnome-open`` exists and + ## used if it does. Next attempt is ``kde-open``, then ``xdg-open``. + ## Otherwise the environment variable ``BROWSER`` is used to determine the + ## default browser to use. + when defined(windows): + discard ShellExecute(0'i32, "open", url, nil, nil, SW_SHOWNORMAL) + elif defined(macosx): + discard execShellCmd("open " & quoteIfContainsWhite(url)) + else: + const attempts = ["gnome-open ", "kde-open ", "xdg-open "] + var u = quoteIfContainsWhite(url) + for a in items(attempts): + if execShellCmd(a & u) == 0: return + for b in getEnv("BROWSER").split(PathSep): + try: + # we use ``startProcess`` here because we don't want to block! + discard startProcess(command=b, args=[url], options={poUseShell}) + return + except EOS: + nil diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim index 93d29189b..210af00fc 100755 --- a/lib/pure/cgi.nim +++ b/lib/pure/cgi.nim @@ -120,51 +120,57 @@ proc getEncodedData(allowedMethods: set[TRequestMethod]): string = if methodNone notin allowedMethods: cgiError("'REQUEST_METHOD' must be 'POST' or 'GET'") +iterator decodeData*(data: string): tuple[key, value: string] = + ## Reads and decodes CGI data and yields the (name, value) pairs the + ## data consists of. + var i = 0 + var name = "" + var value = "" + # decode everything in one pass: + while data[i] != '\0': + setLen(name, 0) # reuse memory + while true: + case data[i] + of '\0': break + of '%': + var x = 0 + handleHexChar(data[i+1], x) + handleHexChar(data[i+2], x) + inc(i, 2) + add(name, chr(x)) + of '+': add(name, ' ') + of '=', '&': break + else: add(name, data[i]) + inc(i) + if data[i] != '=': cgiError("'=' expected") + inc(i) # skip '=' + setLen(value, 0) # reuse memory + while true: + case data[i] + of '%': + var x = 0 + handleHexChar(data[i+1], x) + handleHexChar(data[i+2], x) + inc(i, 2) + add(value, chr(x)) + of '+': add(value, ' ') + of '&', '\0': break + else: add(value, data[i]) + inc(i) + yield (name, value) + if data[i] == '&': inc(i) + elif data[i] == '\0': break + else: cgiError("'&' expected") + iterator decodeData*(allowedMethods: set[TRequestMethod] = {methodNone, methodPost, methodGet}): tuple[key, value: string] = ## Reads and decodes CGI data and yields the (name, value) pairs the ## data consists of. If the client does not use a method listed in the ## `allowedMethods` set, an `ECgi` exception is raised. - var enc = getEncodedData(allowedMethods) - if not isNil(enc): - # decode everything in one pass: - var i = 0 - var name = "" - var value = "" - while enc[i] != '\0': - setLen(name, 0) # reuse memory - while true: - case enc[i] - of '\0': break - of '%': - var x = 0 - handleHexChar(enc[i+1], x) - handleHexChar(enc[i+2], x) - inc(i, 2) - add(name, chr(x)) - of '+': add(name, ' ') - of '=', '&': break - else: add(name, enc[i]) - inc(i) - if enc[i] != '=': cgiError("'=' expected") - inc(i) # skip '=' - setLen(value, 0) # reuse memory - while true: - case enc[i] - of '%': - var x = 0 - handleHexChar(enc[i+1], x) - handleHexChar(enc[i+2], x) - inc(i, 2) - add(value, chr(x)) - of '+': add(value, ' ') - of '&', '\0': break - else: add(value, enc[i]) - inc(i) - yield (name, value) - if enc[i] == '&': inc(i) - elif enc[i] == '\0': break - else: cgiError("'&' expected") + var data = getEncodedData(allowedMethods) + if not isNil(data): + for key, value in decodeData(data): + yield key, value proc readData*(allowedMethods: set[TRequestMethod] = {methodNone, methodPost, methodGet}): PStringTable = diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 85ac9c83c..1bbe55bb9 100755 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -577,7 +577,7 @@ proc cmpPaths*(pathA, pathB: string): int {.noSideEffect.} = proc sameFile*(path1, path2: string): bool = ## Returns True if both pathname arguments refer to the same file or ## directory (as indicated by device number and i-node number). - ## Raises an exception if an os.stat() call on either pathname fails. + ## Raises an exception if an stat() call on either pathname fails. when defined(Windows): var a, b: TWin32FindData diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index be2e4434a..9419b82b9 100755 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -7,26 +7,7 @@ # distribution, for details about the copyright. # -## This module implements a simple portable type-safe sockets layer. **Note**: -## This module is incomplete and probably buggy. It does not work on Windows -## yet. Help if you are interested. - -# TODO: -# getservbyname(name, proto) -# getservbyport(port, proto) -# gethostbyname(name) -# gethostbyaddr(addr) -# shutdown(sock, how) -# connect(sock, address, port) -# select({ socket, ... }, timeout) - -# sendto -# recvfrom - -# bind(socket, address, port) - -# getsockopt(socket, level, optname) -# setsockopt(socket, level, optname, value) +## This module implements a simple portable type-safe sockets layer. import os @@ -35,6 +16,8 @@ when defined(Windows): else: import posix +# Note: The enumerations are mapped to Window's constants. + type TSocket* = distinct cint ## socket type TPort* = distinct int16 ## port type @@ -42,87 +25,149 @@ type TDomain* = 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). - AF_INET, ## for network protocol IPv4 or - AF_INET6 ## for network protocol IPv6. - - TType* = enum ## second argument to `socket` proc - SOCK_STREAM, ## reliable stream-oriented service or Stream Sockets - SOCK_DGRAM, ## datagram service or Datagram Sockets - SOCK_SEQPACKET, ## reliable sequenced packet service, or - SOCK_RAW ## raw protocols atop the network layer. - - TProtocol* = enum ## third argument to `socket` proc - IPPROTO_TCP, ## Transmission control protocol. - IPPROTO_UDP, ## User datagram protocol. - IPPROTO_IP, ## Internet protocol. - IPPROTO_IPV6, ## Internet Protocol Version 6. - IPPROTO_RAW, ## Raw IP Packets Protocol. - IPPROTO_ICMP ## Control message protocol. + AF_UNIX, ## for local socket (using a file). Unsupported on Windows. + AF_INET = 2, ## for network protocol IPv4 or + AF_INET6 = 23 ## for network protocol IPv6. + + TType* = enum ## second argument to `socket` proc + SOCK_STREAM = 1, ## reliable stream-oriented service or Stream Sockets + SOCK_DGRAM = 2, ## datagram service or Datagram Sockets + SOCK_RAW = 3, ## raw protocols atop the network layer. + SOCK_SEQPACKET = 5 ## reliable sequenced packet service, or + + TProtocol* = enum ## third argument to `socket` proc + IPPROTO_TCP = 6, ## Transmission control protocol. + IPPROTO_UDP = 17, ## User datagram protocol. + IPPROTO_IP, ## Internet protocol. Unsupported on Windows. + IPPROTO_IPV6, ## Internet Protocol Version 6. Unsupported on Windows. + IPPROTO_RAW, ## Raw IP Packets Protocol. Unsupported on Windows. + IPPROTO_ICMP ## Control message protocol. Unsupported on Windows. + + TServent* {.pure, final.} = object ## information about a service + name*: string + aliases*: seq[string] + port*: TPort + proto*: string + + Thostent* {.pure, final.} = object ## information about a given host + name*: string + aliases*: seq[string] + addrtype*: TDomain + length*: int + addrList*: seq[string] const InvalidSocket* = TSocket(-1'i32) ## invalid socket number proc `==`*(a, b: TSocket): bool {.borrow.} + ## ``==`` for sockets. + proc `==`*(a, b: TPort): bool {.borrow.} + ## ``==`` for ports. -proc `$`* (p: TPort): string = result = $ze(int16(p)) - -proc ToInt(domain: TDomain): cint = - case domain - of AF_UNIX: result = posix.AF_UNIX - of AF_INET: result = posix.AF_INET - of AF_INET6: result = posix.AF_INET6 - -proc ToInt(typ: TType): cint = - case typ - of SOCK_STREAM: result = posix.SOCK_STREAM - of SOCK_DGRAM: result = posix.SOCK_DGRAM - of SOCK_SEQPACKET: result = posix.SOCK_SEQPACKET - of SOCK_RAW: result = posix.SOCK_RAW - -proc ToInt(p: TProtocol): cint = - case p - of IPPROTO_TCP: result = posix.IPPROTO_TCP - of IPPROTO_UDP: result = posix.IPPROTO_UDP - of IPPROTO_IP: result = posix.IPPROTO_IP - of IPPROTO_IPV6: result = posix.IPPROTO_IPV6 - of IPPROTO_RAW: result = posix.IPPROTO_RAW - of IPPROTO_ICMP: result = posix.IPPROTO_ICMP - -proc socket*(domain: TDomain = AF_INET6, typ: TType = SOCK_STREAM, +proc `$`*(p: TPort): string = + ## returns the port number as a string + result = $ze(int16(p)) + +proc ntohl*(x: int32): int32 = + ## Converts 32-bit integers from network to host byte order. + ## On machines where the host byte order is the same as network byte order, + ## this is a no-op; otherwise, it performs a 4-byte swap operation. + when cpuEndian == bigEndian: result = x + else: result = (x shr 24'i32) or + (x shr 8'i32 and 0xff00'i32) or + (x shl 8'i32 and 0xff0000'i32) or + (x shl 24'i32) + +proc ntohs*(x: int16): int16 = + ## Converts 16-bit integers from network to host byte order. On machines + ## where the host byte order is the same as network byte order, this is + ## a no-op; otherwise, it performs a 2-byte swap operation. + when cpuEndian == bigEndian: result = x + else: result = (x shr 8'i16) or (x shl 8'i16) + +proc htonl*(x: int32): int32 = + ## Converts 32-bit integers from host to network byte order. On machines + ## where the host byte order is the same as network byte order, this is + ## a no-op; otherwise, it performs a 4-byte swap operation. + result = sockets.ntohl(x) + +proc htons*(x: int16): int16 = + ## Converts 16-bit positive integers from host to network byte order. + ## On machines where the host byte order is the same as network byte + ## order, this is a no-op; otherwise, it performs a 2-byte swap operation. + result = sockets.ntohs(x) + +when defined(Posix): + proc ToInt(domain: TDomain): cint = + case domain + of AF_UNIX: result = posix.AF_UNIX + of AF_INET: result = posix.AF_INET + of AF_INET6: result = posix.AF_INET6 + else: nil + + proc ToInt(typ: TType): cint = + case typ + of SOCK_STREAM: result = posix.SOCK_STREAM + of SOCK_DGRAM: result = posix.SOCK_DGRAM + of SOCK_SEQPACKET: result = posix.SOCK_SEQPACKET + of SOCK_RAW: result = posix.SOCK_RAW + else: nil + + proc ToInt(p: TProtocol): cint = + case p + of IPPROTO_TCP: result = posix.IPPROTO_TCP + of IPPROTO_UDP: result = posix.IPPROTO_UDP + of IPPROTO_IP: result = posix.IPPROTO_IP + of IPPROTO_IPV6: result = posix.IPPROTO_IPV6 + of IPPROTO_RAW: result = posix.IPPROTO_RAW + of IPPROTO_ICMP: result = posix.IPPROTO_ICMP + else: nil + +proc socket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, protocol: TProtocol = IPPROTO_TCP): TSocket = ## creates a new socket; returns `InvalidSocket` if an error occurs. - result = TSocket(posix.socket(ToInt(domain), ToInt(typ), ToInt(protocol))) + when defined(Windows): + result = TSocket(winlean.socket(ord(domain), ord(typ), ord(protocol))) + else: + result = TSocket(posix.socket(ToInt(domain), ToInt(typ), ToInt(protocol))) proc listen*(socket: TSocket, attempts = 5) = ## listens to socket. - if posix.listen(cint(socket), cint(attempts)) < 0'i32: OSError() + if listen(cint(socket), cint(attempts)) < 0'i32: OSError() proc bindAddr*(socket: TSocket, port = TPort(0)) = + ## binds a port number to a socket. var name: Tsockaddr_in - name.sin_family = posix.AF_INET - name.sin_port = htons(int16(port)) - name.sin_addr.s_addr = htonl(INADDR_ANY) + when defined(Windows): + name.sin_family = int16(ord(AF_INET)) + else: + name.sin_family = posix.AF_INET + name.sin_port = sockets.htons(int16(port)) + name.sin_addr.s_addr = sockets.htonl(INADDR_ANY) if bindSocket(cint(socket), cast[ptr TSockAddr](addr(name)), sizeof(name)) < 0'i32: OSError() proc getSockName*(socket: TSocket): TPort = + ## returns the socket's associated port number. var name: Tsockaddr_in - name.sin_family = posix.AF_INET + when defined(Windows): + name.sin_family = int16(ord(AF_INET)) + else: + name.sin_family = posix.AF_INET #name.sin_port = htons(cint16(port)) #name.sin_addr.s_addr = htonl(INADDR_ANY) var namelen: cint = sizeof(name) if getsockname(cint(socket), cast[ptr TSockAddr](addr(name)), addr(namelen)) == -1'i32: OSError() - result = TPort(ntohs(name.sin_port)) + result = TPort(sockets.ntohs(name.sin_port)) proc accept*(server: TSocket): TSocket = ## waits for a client and returns its socket var client: Tsockaddr_in - var clientLen: TsockLen = sizeof(client) + var clientLen: cint = sizeof(client) result = TSocket(accept(cint(server), cast[ptr TSockAddr](addr(client)), addr(clientLen))) @@ -133,8 +178,163 @@ proc close*(socket: TSocket) = else: discard posix.close(cint(socket)) +proc getServByName*(name, proto: string): TServent = + ## well-known getservbyname proc. + when defined(Windows): + var s = winlean.getservbyname(name, proto) + else: + var s = posix.getservbyname(name, proto) + if s == nil: OSError() + result.name = $s.s_name + result.aliases = cstringArrayToSeq(s.s_aliases) + result.port = TPort(s.s_port) + result.proto = $s.s_proto + +proc getServByPort*(port: TPort, proto: string): TServent = + ## well-known getservbyport proc. + when defined(Windows): + var s = winlean.getservbyport(ze(int16(port)), proto) + else: + var s = posix.getservbyport(ze(int16(port)), proto) + if s == nil: OSError() + result.name = $s.s_name + result.aliases = cstringArrayToSeq(s.s_aliases) + result.port = TPort(s.s_port) + result.proto = $s.s_proto + +proc getHostByName*(name: string): THostEnt = + ## well-known gethostbyname proc. + when defined(Windows): + var s = winlean.gethostbyname(name) + else: + var s = posix.gethostbyname(name) + if s == nil: OSError() + result.name = $s.h_name + result.aliases = cstringArrayToSeq(s.h_aliases) + when defined(windows): + result.addrType = TDomain(s.h_addrtype) + else: + if s.h_addrtype == posix.AF_INET: + result.addrType = AF_INET + elif s.h_addrtype == posix.AF_INET6: + result.addrType = AF_INET6 + else: + OSError("unknown h_addrtype") + result.addrList = cstringArrayToSeq(s.h_addr_list) + result.length = int(s.h_length) + +proc getSockOptInt*(socket: TSocket, level, optname: int): int = + ## getsockopt for integer options. + var res: cint + var size: cint = sizeof(res) + if getsockopt(cint(socket), cint(level), cint(optname), + addr(res), addr(size)) < 0'i32: + OSError() + result = int(res) + +proc setSockOptInt*(socket: TSocket, level, optname, optval: int) = + ## setsockopt for integer options. + var value = cint(optval) + if setsockopt(cint(socket), cint(level), cint(optname), addr(value), + sizeof(value)) < 0'i32: + OSError() + +proc connect*(socket: TSocket, name: string, port = TPort(0), + af: TDomain = AF_INET) = + ## well-known connect operation. Already does ``htons`` on the port number, + ## so you shouldn't do it. + var s: TSockAddrIn + s.sin_addr.s_addr = inet_addr(name) + s.sin_port = sockets.htons(int16(port)) + when defined(windows): + s.sin_family = toU16(ord(af)) + else: + case af + of AF_UNIX: s.sin_family = posix.AF_UNIX + of AF_INET: s.sin_family = posix.AF_INET + of AF_INET6: s.sin_family = posix.AF_INET6 + else: nil + if connect(cint(socket), cast[ptr TSockAddr](addr(s)), sizeof(s)) < 0'i32: + OSError() + +#proc recvfrom*(s: TWinSocket, buf: cstring, len, flags: cint, +# fromm: ptr TSockAddr, fromlen: ptr cint): cint + +#proc sendto*(s: TWinSocket, buf: cstring, len, flags: cint, +# to: ptr TSockAddr, tolen: cint): cint + +proc createFdSet(fd: var TFdSet, s: seq[TSocket], m: var int) = + FD_ZERO(fd) + for i in items(s): + m = max(m, int(i)) + FD_SET(cint(i), fd) + +proc pruneSocketSet(s: var seq[TSocket], fd: var TFdSet) = + var i = 0 + var L = s.len + while i < L: + if FD_ISSET(cint(s[i]), fd) != 0'i32: + s[i] = s[L-1] + dec(L) + else: + inc(i) + setLen(s, L) + +proc select*(readfds, writefds, exceptfds: var seq[TSocket], + timeout = 500): int = + ## select with a sensible Nimrod interface. `timeout` is in miliseconds. + var tv: TTimeVal + tv.tv_sec = 0 + tv.tv_usec = timeout * 1000 + + var rd, wr, ex: TFdSet + var m = 0 + createFdSet((rd), readfds, m) + createFdSet((wr), writefds, m) + createFdSet((ex), exceptfds, m) + + result = int(select(cint(m), addr(rd), addr(wr), addr(ex), addr(tv))) + + pruneSocketSet(readfds, (rd)) + pruneSocketSet(writefds, (wr)) + pruneSocketSet(exceptfds, (ex)) + +proc select*(readfds, writefds: var seq[TSocket], + timeout = 500): int = + ## select with a sensible Nimrod interface. `timeout` is in miliseconds. + var tv: TTimeVal + tv.tv_sec = 0 + tv.tv_usec = timeout * 1000 + + var rd, wr: TFdSet + var m = 0 + createFdSet((rd), readfds, m) + createFdSet((wr), writefds, m) + + result = int(select(cint(m), addr(rd), addr(wr), nil, addr(tv))) + + pruneSocketSet(readfds, (rd)) + pruneSocketSet(writefds, (wr)) + + +proc select*(readfds: var seq[TSocket], timeout = 500): int = + ## select with a sensible Nimrod interface. `timeout` is in miliseconds. + var tv: TTimeVal + tv.tv_sec = 0 + tv.tv_usec = timeout * 1000 + + var rd: TFdSet + var m = 0 + createFdSet((rd), readfds, m) + + result = int(select(cint(m), addr(rd), nil, nil, addr(tv))) + + pruneSocketSet(readfds, (rd)) + + proc recvLine*(socket: TSocket, line: var string): bool = - ## returns false if no further data is available. + ## returns false if no further data is available. `line` must be initalized + ## and not nil! setLen(line, 0) while true: var c: char @@ -150,11 +350,11 @@ proc recvLine*(socket: TSocket, line: var string): bool = add(line, c) proc recv*(socket: TSocket, data: pointer, size: int): int = - ## receive data from a socket - result = posix.recv(cint(socket), data, size, 0'i32) + ## receives data from a socket + result = recv(cint(socket), data, size, 0'i32) proc recv*(socket: TSocket): string = - ## receive all the data from the socket + ## receives all the data from the socket const bufSize = 200 var buf = newString(bufSize) result = "" @@ -173,36 +373,15 @@ proc skip*(socket: TSocket) = dealloc(buf) proc send*(socket: TSocket, data: pointer, size: int): int = - result = posix.send(cint(socket), data, size, 0'i32) + ## sends data to a socket. + result = send(cint(socket), data, size, 0'i32) proc send*(socket: TSocket, data: string) = + ## sends data to a socket. if send(socket, cstring(data), data.len) != data.len: OSError() -proc ntohl*(x: int32): int32 = - ## Convert 32-bit integers from network to host byte order. - ## On machines where the host byte order is the same as network byte order, - ## this is a no-op; otherwise, it performs a 4-byte swap operation. - when cpuEndian == bigEndian: result = x - else: result = (x shr 24'i32) or - (x shr 8'i32 and 0xff00'i32) or - (x shl 8'i32 and 0xff0000'i32) or - (x shl 24'i32) - -proc ntohs*(x: int16): int16 = - ## Convert 16-bit integers from network to host byte order. On machines - ## where the host byte order is the same as network byte order, this is - ## a no-op; otherwise, it performs a 2-byte swap operation. - when cpuEndian == bigEndian: result = x - else: result = (x shr 8'i16) or (x shl 8'i16) +when defined(Windows): + var wsa: TWSADATA + if WSAStartup(0x0101'i16, wsa) != 0: OSError() -proc htonl*(x: int32): int32 = - ## Convert 32-bit integers from host to network byte order. On machines - ## where the host byte order is the same as network byte order, this is - ## a no-op; otherwise, it performs a 4-byte swap operation. - result = sockets.ntohl(x) -proc htons*(x: int16): int16 = - ## Convert 16-bit positive integers from host to network byte order. - ## On machines where the host byte order is the same as network byte - ## order, this is a no-op; otherwise, it performs a 2-byte swap operation. - result = sockets.ntohs(x) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index d7fd69f61..1dfb070bc 100755 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -1,7 +1,7 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -655,8 +655,7 @@ proc replace*(s: string, sub, by: char): string = proc delete*(s: var string, first, last: int) = ## Deletes in `s` the characters at position `first`..`last`. This modifies ## `s` itself, it does not return a copy. - var - i = first + var i = first # example: "abc___uvwxyz\0" (___ is to be deleted) # --> first == 3, last == 5 # s[first..] = s[last+1..] @@ -851,6 +850,7 @@ proc escape*(s: string, prefix = "\"", suffix = "\""): string = proc validEmailAddress*(s: string): bool = ## returns true if `s` seems to be a valid e-mail address. ## The checking also uses a domain list. + ## Note: This will be moved into another module soon. const chars = Letters + Digits + {'!','#','$','%','&', '\'','*','+','/','=','?','^','_','`','{','}','|','~','-','.'} diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 8c21b6027..a54af3254 100755 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -1,7 +1,7 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. diff --git a/lib/system.nim b/lib/system.nim index 25e914b63..f287d7bda 100755 --- a/lib/system.nim +++ b/lib/system.nim @@ -743,6 +743,7 @@ type # these work for most platforms: cstringArray* {.importc: "char**", nodecl.} = ptr array [0..50_000, cstring] ## This is binary compatible to the type ``char**`` in *C*. The array's ## high value is large enough to disable bounds checking in practice. + ## Use cstringArrayToSeq to convert it into a ``seq[string]``. TEndian* = enum ## is a type describing the endianness of a processor. littleEndian, bigEndian @@ -1468,6 +1469,19 @@ when not defined(EcmaScript) and not defined(NimrodVM): echo(errormsg) quit(quitFailure) + proc cstringArrayToSeq*(a: cstringArray, len: int): seq[string] = + ## converts a ``cstringArray`` to a ``seq[string]``. `a` is supposed to be + ## of length ``len``. + newSeq(result, len) + for i in 0..len-1: result[i] = $a[i] + + proc cstringArrayToSeq*(a: cstringArray): seq[string] = + ## converts a ``cstringArray`` to a ``seq[string]``. `a` is supposed to be + ## terminated by ``nil``. + var L = 0 + while a[L] != nil: inc(L) + result = cstringArrayToSeq(a, L) + # ---------------------------------------------------------------------------- include "system/excpt" diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index f384a04e8..ebf0fdc96 100755 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -1,7 +1,7 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -197,3 +197,147 @@ proc ShellExecute*(HWND: THandle, lpOperation, lpFile, nShowCmd: int32): THandle{. stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".} +const + WSADESCRIPTION_LEN* = 256 + WSASYS_STATUS_LEN* = 128 + FD_SETSIZE* = 64 + MSG_PEEK* = 2 + + INADDR_ANY* = 0 + INADDR_LOOPBACK* = 0x7F000001 + INADDR_BROADCAST* = -1 + INADDR_NONE* = -1 + +type + TWSAData* {.pure, final.} = object + wVersion, wHighVersion: int16 + szDescription: array[0..WSADESCRIPTION_LEN, char] + szSystemStatus: array[0..WSASYS_STATUS_LEN, char] + iMaxSockets, iMaxUdpDg: int16 + lpVendorInfo: cstring + + TSockAddr* {.pure, final.} = object + sa_family*: int16 # unsigned + sa_data: array[0..13, char] + + TInAddr* {.pure, final.} = object ## struct in_addr + s_addr*: int32 # IP address + + Tsockaddr_in* {.pure, final.} = object + sin_family*: int16 + sin_port*: int16 # unsigned + sin_addr*: TInAddr + sin_zero*: array[0..7, char] + + Tin6_addr* {.pure, final.} = object + bytes*: array[0..15, char] + + Tsockaddr_in6* {.pure, final.} = object + sin6_family*: int16 + sin6_port*: int16 # unsigned + sin6_flowinfo*: int32 # unsigned + sin6_addr*: Tin6_addr + sin6_scope_id*: int32 # unsigned + + Tsockaddr_in6_old* {.pure, final.} = object + sin6_family*: int16 + sin6_port*: int16 # unsigned + sin6_flowinfo*: int32 # unsigned + sin6_addr*: Tin6_addr + + TServent* {.pure, final.} = object + s_name*: cstring + s_aliases*: cstringArray + when defined(cpu64): + s_proto*: cstring + s_port*: int16 + else: + s_port*: int16 + s_proto*: cstring + + Thostent* {.pure, final.} = object + h_name*: cstring + h_aliases*: cstringArray + h_addrtype*: int16 + h_length*: int16 + h_addr_list*: cstringArray + + TWinSocket* = cint + + TFdSet* {.pure, final.} = object + fd_count*: cint # unsigned + fd_array*: array[0..FD_SETSIZE-1, TWinSocket] + + TTimeval* {.pure, final.} = object + tv_sec*, tv_usec*: int32 + +proc getservbyname*(name, proto: cstring): ptr TServent {. + stdcall, importc: "getservbyname", dynlib: "Ws2_32.dll".} + +proc getservbyport*(port: cint, proto: cstring): ptr TServent {. + stdcall, importc: "getservbyport", dynlib: "Ws2_32.dll".} + +proc gethostbyname*(name: cstring): ptr THostEnt {. + stdcall, importc: "gethostbyname", dynlib: "Ws2_32.dll".} + +proc socket*(af, typ, protocol: cint): TWinSocket {. + stdcall, importc: "socket", dynlib: "Ws2_32.dll".} + +proc closesocket*(s: TWinSocket): cint {. + stdcall, importc: "closesocket", dynlib: "Ws2_32.dll".} + +proc accept*(s: TWinSocket, a: ptr TSockAddr, addrlen: ptr cint): TWinSocket {. + stdcall, importc: "accept", dynlib: "Ws2_32.dll".} +proc bindSocket*(s: TWinSocket, name: ptr TSockAddr, namelen: cint): cint {. + stdcall, importc: "bind", dynlib: "Ws2_32.dll".} +proc connect*(s: TWinSocket, name: ptr TSockAddr, namelen: cint): cint {. + stdcall, importc: "connect", dynlib: "Ws2_32.dll".} +proc getsockname*(s: TWinSocket, name: ptr TSockAddr, + namelen: ptr cint): cint {. + stdcall, importc: "getsockname", dynlib: "Ws2_32.dll".} +proc getsockopt*(s: TWinSocket, level, optname: cint, optval: pointer, + optlen: ptr cint): cint {. + stdcall, importc: "getsockopt", dynlib: "Ws2_32.dll".} +proc setsockopt*(s: TWinSocket, level, optname: cint, optval: pointer, + optlen: cint): cint {. + stdcall, importc: "setsockopt", dynlib: "Ws2_32.dll".} + +proc listen*(s: TWinSocket, backlog: cint): cint {. + stdcall, importc: "listen", dynlib: "Ws2_32.dll".} +proc recv*(s: TWinSocket, buf: pointer, len, flags: cint): cint {. + stdcall, importc: "recv", dynlib: "Ws2_32.dll".} +proc recvfrom*(s: TWinSocket, buf: cstring, len, flags: cint, + fromm: ptr TSockAddr, fromlen: ptr cint): cint {. + stdcall, importc: "recvfrom", dynlib: "Ws2_32.dll".} +proc select*(nfds: cint, readfds, writefds, exceptfds: ptr TFdSet, + timeout: ptr TTimeval): cint {. + stdcall, importc: "select", dynlib: "Ws2_32.dll".} +proc send*(s: TWinSocket, buf: pointer, len, flags: cint): cint {. + stdcall, importc: "send", dynlib: "Ws2_32.dll".} +proc sendto*(s: TWinSocket, buf: cstring, len, flags: cint, + to: ptr TSockAddr, tolen: cint): cint {. + stdcall, importc: "sendto", dynlib: "Ws2_32.dll".} + +proc shutdown*(s: TWinSocket, how: cint): cint {. + stdcall, importc: "shutdown", dynlib: "Ws2_32.dll".} + +proc inet_addr*(cp: cstring): int32 {. + stdcall, importc: "inet_addr", dynlib: "Ws2_32.dll".} + +proc WSAFDIsSet(s: TWinSocket, FDSet: var TFDSet): bool {. + stdcall, importc: "__WSAFDIsSet", dynlib: "Ws2_32.dll".} + +proc FD_ISSET*(Socket: TWinSocket, FDSet: var TFDSet): cint = + result = if WSAFDIsSet(Socket, FDSet): 1'i32 else: 0'i32 + +proc FD_SET*(Socket: TWinSocket, FDSet: var TFDSet) = + if FDSet.fd_count < FD_SETSIZE: + FDSet.fd_array[int(FDSet.fd_count)] = Socket + inc(FDSet.fd_count) + +proc FD_ZERO*(FDSet: var TFDSet) = + FDSet.fd_count = 0 + +proc WSAStartup*(wVersionRequired: int16, WSData: var TWSAData): cint {. + stdcall, importc: "WSAStartup", dynlib: "Ws2_32.dll".} + |