diff --git a/blinkenlicht/bl.fnl b/blinkenlicht/bl.fnl
index f6117d9..d8c3330 100644
--- a/blinkenlicht/bl.fnl
+++ b/blinkenlicht/bl.fnl
@@ -1,9 +1,7 @@
 (local {: bar : indicator : stylesheet  : run} (require :blinkenlicht))
 (local {: view} (require :fennel))
 
-(local posix (require :posix))
-(local fcntl (require :posix.fcntl))
-
+(local iostream (require :iostream))
 (local metric (require :metric))
 
 (stylesheet "licht.css")
@@ -42,10 +40,7 @@
                     {:text v})
                  }))
 
-   (let [f (io.open "/tmp/statuspipe" :r)]
-     (fcntl.fcntl (posix.stdio.fileno f)
-                  fcntl.F_SETFL fcntl.O_NONBLOCK)
-
+   (let [f (iostream.open "/tmp/statuspipe" :r)]
      (indicator {
                  ;; this is a guide to tell blinkenlicht when it might
                  ;; be worth calling your `content` function. Your
@@ -59,7 +54,7 @@
                  ;; { :icon "face-sad" } - render icon from theme or pathname
                  ;; { :classes ["foo" "bar"] - add CSS classes to widget
                  :refresh
-                 #(let [l (posix.unistd.read (posix.stdio.fileno f) 1024)]
+                 #(let [l (f:read 1024)]
                     (if l
                         {:text l}))
                  }))
diff --git a/blinkenlicht/blinkenlicht.fnl b/blinkenlicht/blinkenlicht.fnl
index d46dce1..67fd1cb 100644
--- a/blinkenlicht/blinkenlicht.fnl
+++ b/blinkenlicht/blinkenlicht.fnl
@@ -131,7 +131,7 @@
     (window:add box)))
 
 (fn gsource-for-file-input [file cb]
-  (let [fd (posix.stdio.fileno file)]
+  (let [fd file.fileno]
     (doto (GLib.unix_fd_source_new fd  GLib.IOCondition.IN)
       (: :set_callback cb))))
 
diff --git a/blinkenlicht/iostream.fnl b/blinkenlicht/iostream.fnl
new file mode 100644
index 0000000..5209545
--- /dev/null
+++ b/blinkenlicht/iostream.fnl
@@ -0,0 +1,16 @@
+(local posix (require :posix))
+(local fcntl (require :posix.fcntl))
+
+(fn open [name direction]
+  (let [flags (match direction
+                :r posix.O_RDONLY
+                :w (+ posix.O_WRONLY posix.O_CREAT))
+        fd (posix.open name flags)]
+    (fcntl.fcntl fd fcntl.F_SETFL fcntl.O_NONBLOCK)
+    {
+     :read #(posix.unistd.read fd $2)   ;XXX needs to check for eof
+     :close #(posix.unistd.close fd)
+     :fileno fd
+     }))
+
+{: open }