Skip to content

Commit d747019

Browse files
basic tty io support
1 parent bfe0468 commit d747019

6 files changed

Lines changed: 134 additions & 14 deletions

File tree

examples/tty-io-test.pxi

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(ns io-test
2+
(:require [pixie.io :as io]
3+
[pixie.system :as sys]
4+
[pixie.io.tty :as tty]))
5+
6+
(io/write-stream tty/stdout "This is on STDOUT\n")
7+
(io/write-stream tty/stderr "This is on STDERR\n")
8+
9+
(loop []
10+
(let [input (io/read-line tty/stdin)]
11+
(io/write-stream tty/stdout (str "You typed: " input "\n"))
12+
(recur)))

pixie/io.pxi

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
result)
152152

153153
(defn open-write
154-
{:doc "Open a file for reading, returning a IInputStream"
154+
{:doc "Open a file for writing, returning a IOutputStream"
155155
:added "0.1"}
156156
[filename]
157157
(assert (string? filename) "Filename must be a string")
@@ -172,6 +172,20 @@
172172
(write-byte fp chr)
173173
nil))))
174174

175+
(defn stream-output-rf [output-stream]
176+
(let [fp (buffered-output-stream output-stream
177+
DEFAULT-BUFFER-SIZE)]
178+
(fn ([] 0)
179+
([_] (dispose! fp))
180+
([_ chr]
181+
(assert (integer? chr))
182+
(write-byte fp chr)
183+
nil))))
184+
185+
(defn write-stream [output-stream val]
186+
(transduce (map int)
187+
(stream-output-rf output-stream)
188+
(str val)))
175189

176190
(defn spit [filename val]
177191
(transduce (map int)

pixie/io/tcp.pxi

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,12 @@
1111
(dispose! @on-connection-cb)
1212
(dispose! bind-addr)))
1313

14-
(defn -prep-uv-buffer-fn [buf read-bytes]
15-
(ffi/ffi-prep-callback
16-
uv/uv_alloc_cb
17-
(fn [handle suggested-size uv-buf]
18-
(try
19-
(let [casted (ffi/cast uv-buf uv/uv_buf_t)]
20-
(ffi/set! casted :base buf)
21-
(ffi/set! casted :len (min suggested-size
22-
(buffer-capacity buf)
23-
read-bytes)))
24-
(catch ex (println ex))))))
25-
2614
(deftype TCPStream [uv-client uv-write-buf]
2715
IInputStream
2816
(read [this buffer len]
2917
(assert (<= (buffer-capacity buffer) len)
3018
"Not enough capacity in the buffer")
31-
(let [alloc-cb (-prep-uv-buffer-fn buffer len)
19+
(let [alloc-cb (uv/-prep-uv-buffer-fn buffer len)
3220
read-cb (atom nil)]
3321
(st/call-cc (fn [k]
3422
(reset! read-cb (ffi/ffi-prep-callback

pixie/io/tty.pxi

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
(ns pixie.io.tty
2+
(:require [pixie.stacklets :as st]
3+
[pixie.streams :refer [IInputStream read IOutputStream write]]
4+
[pixie.uv :as uv]
5+
[pixie.io :as io]
6+
[pixie.system :as sys]
7+
[pixie.ffi :as ffi]))
8+
9+
(deftype TTYInputStream [uv-client uv-write-buf]
10+
IInputStream
11+
(read [this buffer len]
12+
(assert (<= (buffer-capacity buffer) len)
13+
"Not enough capacity in the buffer")
14+
(let [alloc-cb (uv/-prep-uv-buffer-fn buffer len)
15+
read-cb (atom nil)]
16+
(st/call-cc (fn [k]
17+
(reset! read-cb (ffi/ffi-prep-callback
18+
uv/uv_read_cb
19+
(fn [stream nread uv-buf]
20+
(set-buffer-count! buffer nread)
21+
(try
22+
(dispose! alloc-cb)
23+
(dispose! @read-cb)
24+
;(dispose! uv-buf)
25+
(uv/uv_read_stop stream)
26+
(st/run-and-process k (or
27+
(st/exception-on-uv-error nread)
28+
nread))
29+
(catch ex
30+
(println ex))))))
31+
(uv/uv_read_start uv-client alloc-cb @read-cb))))))
32+
33+
(deftype TTYOutputStream [uv-client uv-write-buf]
34+
IOutputStream
35+
(write [this buffer]
36+
(let [write-cb (atom nil)
37+
uv_write (uv/uv_write_t)]
38+
(ffi/set! uv-write-buf :base buffer)
39+
(ffi/set! uv-write-buf :len (count buffer))
40+
(st/call-cc
41+
(fn [k]
42+
(reset! write-cb (ffi/ffi-prep-callback
43+
uv/uv_write_cb
44+
(fn [req status]
45+
(try
46+
(dispose! @write-cb)
47+
(st/run-and-process k status)
48+
(catch ex
49+
(println ex))))))
50+
(uv/uv_write uv_write uv-client uv-write-buf 1 @write-cb)))))
51+
52+
IDisposable
53+
(-dispose! [this]
54+
(dispose! uv-write-buf)
55+
(uv/uv_close uv-client st/close_cb)))
56+
57+
(defn tty-output-stream [fd]
58+
;(assert (= uv/UV_TTY (uv/uv_guess_handle fd)) "fd is not a TTY")
59+
(let [buf (uv/uv_buf_t)
60+
tty (uv/uv_tty_t)]
61+
(uv/uv_tty_init (uv/uv_default_loop) tty fd 0)
62+
(->TTYOutputStream tty buf)))
63+
64+
(defn tty-input-stream [fd]
65+
;(assert (= uv/UV_TTY (uv/uv_guess_handle fd)) "fd is not a TTY")
66+
(let [buf (uv/uv_buf_t)
67+
tty (uv/uv_tty_t)]
68+
(uv/uv_tty_init (uv/uv_default_loop) tty fd 0)
69+
(->TTYInputStream tty buf)))
70+
71+
(def stdin (tty-input-stream sys/stdin))
72+
(def stdout (tty-output-stream sys/stdout))
73+
(def stderr (tty-output-stream sys/stderr))

pixie/system.pxi

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
(ns pixie.system
2+
(:require [pixie.ffi-infer :as i]))
3+
4+
(i/with-config {:library "c" :imports ["stdio.h"]}
5+
(i/defconst STDIN_FILENO)
6+
(i/defconst STDOUT_FILENO)
7+
(i/defconst STDERR_FILENO))
8+
9+
(def fdopen (ffi-fn libc "fdopen" [CInt CCharP] CVoidP))
10+
11+
(def stdin STDIN_FILENO)
12+
(def stderr STDOUT_FILENO)
13+
(def stdout STDERR_FILENO)

pixie/uv.pxi

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,14 @@
189189
(f/defcfn uv_async_init)
190190
(f/defcfn uv_async_send)
191191

192+
; TTY
193+
(f/defcfn uv_tty_init)
194+
(f/defconst UV_TTY_MODE_NORMAL)
195+
(f/defcfn uv_guess_handle)
196+
;(f/defcfn uv_tty_set_mode)
197+
(f/defcstruct uv_tty_t [])
198+
(f/defconst UV_TTY)
199+
192200

193201
; TCP Networking
194202
(f/defcstruct uv_tcp_t [])
@@ -243,3 +251,15 @@
243251
~@args
244252
@cb#)))]
245253
(pixie.stacklets/call-cc f)))))
254+
255+
(defn -prep-uv-buffer-fn [buf read-bytes]
256+
(ffi/ffi-prep-callback
257+
uv_alloc_cb
258+
(fn [handle suggested-size uv-buf]
259+
(try
260+
(let [casted (ffi/cast uv-buf uv_buf_t)]
261+
(ffi/set! casted :base buf)
262+
(ffi/set! casted :len (min suggested-size
263+
(buffer-capacity buf)
264+
read-bytes)))
265+
(catch ex (println ex))))))

0 commit comments

Comments
 (0)