summary refs log tree commit diff stats
path: root/lib/posix
diff options
context:
space:
mode:
Diffstat (limited to 'lib/posix')
-rw-r--r--lib/posix/posix.nim59
-rw-r--r--lib/posix/termios.nim261
2 files changed, 298 insertions, 22 deletions
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index deb120372..0c7b84090 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -70,17 +70,20 @@ const
   STDIN_FILENO* = 0  ## File number of stdin;
   STDOUT_FILENO* = 1 ## File number of stdout;
 
-when defined(endb):
-  # to not break bootstrapping again ...
-  type
-    TDIR* {.importc: "DIR", header: "<dirent.h>",
-            final, pure, incompleteStruct.} = object
-      ## A type representing a directory stream.
-else:
-  type
-    TDIR* {.importc: "DIR", header: "<dirent.h>",
-            final, pure.} = object
-      ## A type representing a directory stream.
+  DT_UNKNOWN* = 0 ## Unknown file type.
+  DT_FIFO* = 1    ## Named pipe, or FIFO.
+  DT_CHR* = 2     ## Character device.
+  DT_DIR* = 4     ## Directory.
+  DT_BLK* = 6     ## Block device.
+  DT_REG* = 8     ## Regular file.
+  DT_LNK* = 10    ## Symbolic link.
+  DT_SOCK* = 12   ## UNIX domain socket.
+  DT_WHT* = 14
+
+type
+  TDIR* {.importc: "DIR", header: "<dirent.h>",
+          incompleteStruct.} = object
+    ## A type representing a directory stream.
 
 type
   SocketHandle* = distinct cint # The type used to represent socket descriptors
@@ -91,6 +94,12 @@ type
   Tdirent* {.importc: "struct dirent",
              header: "<dirent.h>", final, pure.} = object ## dirent_t struct
     d_ino*: Tino  ## File serial number.
+    when defined(linux) or defined(macosx) or defined(bsd):
+      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(bsd):
+        d_off*: TOff  ## Not an offset. Value that ``telldir()`` would return.
     d_name*: array [0..255, char] ## Name of entry.
 
   Tflock* {.importc: "struct flock", final, pure,
@@ -1405,14 +1414,6 @@ var
     ## Report status of stopped child process.
   WEXITSTATUS* {.importc, header: "<sys/wait.h>".}: cint
     ## Return exit status.
-  WIFCONTINUED* {.importc, header: "<sys/wait.h>".}: cint
-    ## True if child has been continued.
-  WIFEXITED* {.importc, header: "<sys/wait.h>".}: cint
-    ## True if child exited normally.
-  WIFSIGNALED* {.importc, header: "<sys/wait.h>".}: cint
-    ## True if child exited due to uncaught signal.
-  WIFSTOPPED* {.importc, header: "<sys/wait.h>".}: cint
-    ## True if child is currently stopped.
   WSTOPSIG* {.importc, header: "<sys/wait.h>".}: cint
     ## Return signal number that caused process to stop.
   WTERMSIG* {.importc, header: "<sys/wait.h>".}: cint
@@ -1559,6 +1560,14 @@ var
   MSG_OOB* {.importc, header: "<sys/socket.h>".}: cint
     ## Out-of-band data.
 
+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
@@ -1570,9 +1579,12 @@ else:
 
 
 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
-    MSG_HAVEMORE* {.importc, header: "<sys/socket.h>".}: cint
-    MSG_NOSIGNAL* = MSG_HAVEMORE
+    SO_NOSIGPIPE* {.importc, header: "<sys/socket.h>".}: cint
 else:
   var
     MSG_NOSIGNAL* {.importc, header: "<sys/socket.h>".}: cint
@@ -1739,7 +1751,10 @@ when hasSpawnH:
   when defined(linux):
     # better be safe than sorry; Linux has this flag, macosx doesn't, don't
     # know about the other OSes
-    var POSIX_SPAWN_USEVFORK* {.importc, header: "<spawn.h>".}: cint
+
+    # 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:
diff --git a/lib/posix/termios.nim b/lib/posix/termios.nim
new file mode 100644
index 000000000..710b2fa6b
--- /dev/null
+++ b/lib/posix/termios.nim
@@ -0,0 +1,261 @@
+#
+#
+#            Nim's Runtime Library
+#        (c) Copyright 2015 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+{.deadCodeElim: on.}
+import posix
+
+type
+  Speed* = cuint
+  Tcflag* = cuint
+
+const
+  NCCS* = 32
+
+type
+  Termios* {.importc: "struct termios", header: "<termios.h>".} = object
+    c_iflag*: Tcflag        # input mode flags
+    c_oflag*: Tcflag        # output mode flags
+    c_cflag*: Tcflag        # control mode flags
+    c_lflag*: Tcflag        # local mode flags
+    c_line*: cuchar         # line discipline
+    c_cc*: array[NCCS, cuchar]  # control characters
+
+# cc characters
+
+const
+  VINTR* = 0
+  VQUIT* = 1
+  VERASE* = 2
+  VKILL* = 3
+  VEOF* = 4
+  VTIME* = 5
+  VMIN* = 6
+  VSWTC* = 7
+  VSTART* = 8
+  VSTOP* = 9
+  VSUSP* = 10
+  VEOL* = 11
+  VREPRINT* = 12
+  VDISCARD* = 13
+  VWERASE* = 14
+  VLNEXT* = 15
+  VEOL2* = 16
+
+# iflag bits
+
+const
+  IGNBRK* = 1
+  BRKINT* = 2
+  IGNPAR* = 4
+  PARMRK* = 10
+  INPCK* = 20
+  ISTRIP* = 40
+  INLCR* = 100
+  IGNCR* = 200
+  ICRNL* = 400
+  IUCLC* = 1000
+  IXON* = 2000
+  IXANY* = 4000
+  IXOFF* = 10000
+  IMAXBEL* = 20000
+  IUTF8* = 40000
+
+# oflag bits
+
+const
+  OPOST* = 1
+  OLCUC* = 2
+  ONLCR* = 4
+  OCRNL* = 10
+  ONOCR* = 20
+  ONLRET* = 40
+  OFILL* = 100
+  OFDEL* = 200
+  NLDLY* = 400
+  NL0* = 0
+  NL1* = 400
+  CRDLY* = 3000
+  CR0* = 0
+  CR1* = 1000
+  CR2* = 2000
+  CR3* = 3000
+  TABDLY* = 14000
+  TAB0* = 0
+  TAB1* = 4000
+  TAB2* = 10000
+  TAB3* = 14000
+  BSDLY* = 20000
+  BS0* = 0
+  BS1* = 20000
+  FFDLY* = 0o000000100000
+  FF0* = 0
+  FF1* = 0o000000100000
+  VTDLY* = 40000
+  VT0* = 0
+  VT1* = 40000
+  XTABS* = 14000
+
+# cflag bit meaning
+
+const
+  CBAUD* = 10017
+  B0* = 0
+  B50* = 1
+  B75* = 2
+  B110* = 3
+  B134* = 4
+  B150* = 5
+  B200* = 6
+  B300* = 7
+  B600* = 10
+  B1200* = 11
+  B1800* = 12
+  B2400* = 13
+  B4800* = 14
+  B9600* = 15
+  B19200* = 16
+  B38400* = 17
+  EXTA* = B19200
+  EXTB* = B38400
+  CSIZE* = 60
+  CS5* = 0
+  CS6* = 20
+  CS7* = 40
+  CS8* = 60
+  CSTOPB* = 100
+  CREAD* = 200
+  PARENB* = 400
+  PARODD* = 1000
+  HUPCL* = 2000
+  CLOCAL* = 4000
+  CBAUDEX* = 10000
+  B57600* = 10001
+  B115200* = 10002
+  B230400* = 10003
+  B460800* = 10004
+  B500000* = 10005
+  B576000* = 10006
+  B921600* = 10007
+  B1000000* = 10010
+  B1152000* = 10011
+  B1500000* = 10012
+  B2000000* = 10013
+  B2500000* = 10014
+  B3000000* = 10015
+  B3500000* = 10016
+  B4000000* = 10017
+  MAX_BAUD* = B4000000
+  CIBAUD* = 2003600000
+  CMSPAR* = 0o010000000000
+  CRTSCTS* = 0o020000000000
+
+# lflag bits
+
+const
+  ISIG* = 1
+  ICANON* = 2
+  XCASE* = 4
+  ECHO* = 10
+  ECHOE* = 20
+  ECHOK* = 40
+  ECHONL* = 100
+  NOFLSH* = 200
+  TOSTOP* = 400
+  ECHOCTL* = 1000
+  ECHOPRT* = 2000
+  ECHOKE* = 4000
+  FLUSHO* = 10000
+  PENDIN* = 40000
+  IEXTEN* = 0o000000100000
+  EXTPROC* = 0o000000200000
+
+# tcflow() and TCXONC use these
+
+const
+  TCOOFF* = 0
+  TCOON* = 1
+  TCIOFF* = 2
+  TCION* = 3
+
+# tcflush() and TCFLSH use these
+
+const
+  TCIFLUSH* = 0
+  TCOFLUSH* = 1
+  TCIOFLUSH* = 2
+
+# tcsetattr uses these
+
+const
+  TCSANOW* = 0
+  TCSADRAIN* = 1
+  TCSAFLUSH* = 2
+
+# Compare a character C to a value VAL from the `cc' array in a
+#   `struct termios'.  If VAL is _POSIX_VDISABLE, no character can match it.
+
+template cceq*(val, c: expr): expr =
+  c == val and val != POSIX_VDISABLE
+
+# Return the output baud rate stored in *TERMIOS_P.
+
+proc cfGetOspeed*(termios: ptr Termios): Speed {.importc: "cfgetospeed",
+    header: "<termios.h>".}
+# Return the input baud rate stored in *TERMIOS_P.
+
+proc cfGetIspeed*(termios: ptr Termios): Speed {.importc: "cfgetispeed",
+    header: "<termios.h>".}
+# Set the output baud rate stored in *TERMIOS_P to SPEED.
+
+proc cfSetOspeed*(termios: ptr Termios; speed: Speed): cint {.
+    importc: "cfsetospeed", header: "<termios.h>".}
+# Set the input baud rate stored in *TERMIOS_P to SPEED.
+
+proc cfSetIspeed*(termios: ptr Termios; speed: Speed): cint {.
+    importc: "cfsetispeed", header: "<termios.h>".}
+# Set both the input and output baud rates in *TERMIOS_OP to SPEED.
+
+proc cfSetSpeed*(termios: ptr Termios; speed: Speed): cint {.
+    importc: "cfsetspeed", header: "<termios.h>".}
+# Put the state of FD into *TERMIOS_P.
+
+proc tcGetAttr*(fd: cint; termios: ptr Termios): cint {.
+    importc: "tcgetattr", header: "<termios.h>".}
+# Set the state of FD to *TERMIOS_P.
+#   Values for OPTIONAL_ACTIONS (TCSA*) are in <bits/termios.h>.
+
+proc tcSetAttr*(fd: cint; optional_actions: cint; termios: ptr Termios): cint {.
+    importc: "tcsetattr", header: "<termios.h>".}
+# Set *TERMIOS_P to indicate raw mode.
+
+proc cfMakeRaw*(termios: ptr Termios) {.importc: "cfmakeraw",
+    header: "<termios.h>".}
+# Send zero bits on FD.
+
+proc tcSendBreak*(fd: cint; duration: cint): cint {.importc: "tcsendbreak",
+    header: "<termios.h>".}
+# Wait for pending output to be written on FD.
+#
+#   This function is a cancellation point and therefore not marked with
+#  .
+
+proc tcDrain*(fd: cint): cint {.importc: "tcdrain", header: "<termios.h>".}
+# Flush pending data on FD.
+#   Values for QUEUE_SELECTOR (TC{I,O,IO}FLUSH) are in <bits/termios.h>.
+
+proc tcFlush*(fd: cint; queue_selector: cint): cint {.importc: "tcflush",
+    header: "<termios.h>".}
+# Suspend or restart transmission on FD.
+#   Values for ACTION (TC[IO]{OFF,ON}) are in <bits/termios.h>.
+
+proc tcFlow*(fd: cint; action: cint): cint {.importc: "tcflow",
+    header: "<termios.h>".}
+# Get process group ID for session leader for controlling terminal FD.
+
+proc tcGetSid*(fd: cint): TPid {.importc: "tcgetsid", header: "<termios.h>".}