diff --git a/unistd-input-stream.lisp b/unistd-input-stream.lisp
new file mode 100644
index 0000000..1039456
--- /dev/null
+++ b/unistd-input-stream.lisp
@@ -0,0 +1,43 @@
+
+(in-package :unistd-stream)
+
+(defclass unistd-input-stream (unistd-stream buffered-input-stream)
+ ()
+ (:documentation "A buffered input stream using UNISTD:READ."))
+
+(defmethod make-stream-input-buffer ((stream unistd-input-stream))
+ (cffi:foreign-alloc :unsigned-char
+ :count (stream-input-buffer-size stream)))
+
+(defmethod discard-stream-input-buffer ((stream unistd-input-stream))
+ (cffi:foreign-free (stream-input-buffer stream))
+ (setf (stream-input-buffer stream) nil))
+
+(defmethod stream-fill-input-buffer ((stream unistd-input-stream))
+ (let* ((buffer (stream-input-buffer stream))
+ (length (stream-input-length stream))
+ (fd (stream-fd stream))
+ (buf (cffi:mem-aptr buffer :unsigned-char length))
+ (buflen (- (stream-input-buffer-size stream) length))
+ (r (if (stream-blocking-p stream)
+ (unistd:read fd buf buflen)
+ (unistd:read-non-blocking fd buf buflen))))
+ (cond ((eq :non-blocking r)
+ :non-blocking)
+ ((= r 0)
+ :eof)
+ ((< r 0)
+ (error 'stream-input-error :stream stream))
+ (t
+ (incf (stream-input-length stream) r)
+ nil))))
+
+(defmethod stream-read-element-from-buffer ((stream unistd-input-stream))
+ (let ((element (cffi:mem-aref (stream-input-buffer stream) :unsigned-char
+ (stream-input-index stream))))
+ (incf (stream-input-index stream))
+ (values element nil)))
+
+(defun unistd-input-stream (fd)
+ "Creates a buffered input stream for file descriptor FD."
+ (make-instance 'unistd-input-stream :fd fd))
diff --git a/unistd-io-stream.lisp b/unistd-io-stream.lisp
new file mode 100644
index 0000000..e34d46c
--- /dev/null
+++ b/unistd-io-stream.lisp
@@ -0,0 +1,16 @@
+
+(in-package :unistd-stream)
+
+(defclass unistd-io-stream (unistd-input-stream unistd-output-stream)
+ ()
+ (:documentation "A buffered input/output stream using
+UNISTD:READ and UNISTD:WRITE."))
+
+(defmethod stream-close ((stream unistd-io-stream))
+ (call-next-method)
+ (cffi:foreign-free (stream-input-buffer stream))
+ (cffi:foreign-free (stream-output-buffer stream)))
+
+(defun unistd-io-stream (fd)
+ "Creates a buffered input/output stream for file descriptor FD."
+ (make-instance 'unistd-io-stream :fd fd))
diff --git a/unistd-output-stream.lisp b/unistd-output-stream.lisp
new file mode 100644
index 0000000..e85e3b2
--- /dev/null
+++ b/unistd-output-stream.lisp
@@ -0,0 +1,49 @@
+
+(in-package :unistd-stream)
+
+(defclass unistd-output-stream (unistd-stream buffered-output-stream)
+ ()
+ (:documentation "A buffered output stream using UNISTD:WRITE."))
+
+(defmethod make-stream-output-buffer ((stream unistd-output-stream))
+ (cffi:foreign-alloc :unsigned-char
+ :count (stream-output-buffer-size stream)))
+
+(defmethod discard-stream-output-buffer ((stream unistd-output-stream))
+ (cffi:foreign-free (stream-output-buffer stream))
+ (setf (stream-output-buffer stream) nil))
+
+(defmethod stream-flush-output-buffer ((stream unistd-output-stream))
+ (let ((buffer (stream-output-buffer stream)))
+ (let* ((fd (stream-fd stream))
+ (index (stream-output-index stream))
+ (buf (cffi:mem-aptr buffer :unsigned-char index))
+ (buflen (- (stream-output-length stream) index))
+ (r (if (stream-blocking-p stream)
+ (unistd:write fd buf buflen)
+ (unistd:write-non-blocking fd buf buflen))))
+ (cond ((eq :non-blocking r)
+ :non-blocking)
+ ((= 0 r)
+ :eof)
+ ((< r 0)
+ (error 'stream-output-error :stream stream))
+ (t
+ (incf (stream-output-index stream) r)
+ (when (= (stream-output-index stream)
+ (stream-output-length stream))
+ (setf (stream-output-index stream) 0
+ (stream-output-length stream) 0))
+ nil)))))
+
+(defmethod stream-write-element-to-buffer ((stream unistd-output-stream)
+ element)
+ (setf (cffi:mem-aref (stream-output-buffer stream) :unsigned-char
+ (stream-output-length stream))
+ element)
+ (incf (stream-output-length stream))
+ nil)
+
+(defun unistd-output-stream (fd)
+ "Creates a buffered output stream for file descriptor FD."
+ (make-instance 'unistd-output-stream :fd fd))
diff --git a/unistd-stream-open.lisp b/unistd-stream-open.lisp
new file mode 100644
index 0000000..d993f83
--- /dev/null
+++ b/unistd-stream-open.lisp
@@ -0,0 +1,35 @@
+
+(in-package :unistd-stream)
+
+(defun compute-flags (read write append non-blocking create)
+ (logior (if append fcntl:+o-append+ 0)
+ (if non-blocking fcntl:+o-nonblock+ 0)
+ (if create fcntl:+o-creat+ 0)
+ (cond ((and read write) fcntl:+o-rdwr+)
+ (read fcntl:+o-rdonly+)
+ (write fcntl:+o-wronly+)
+ (t 0))))
+
+(defun compute-class (read write)
+ (cond ((and read write) 'unistd-io-stream)
+ (read 'unistd-input-stream)
+ (write 'unistd-output-stream)))
+
+(defun unistd-stream-open (pathname &key
+ read write append
+ non-blocking
+ (create #o777)
+ (input-buffer-size
+ *stream-default-buffer-size*)
+ (output-buffer-size
+ *stream-default-buffer-size*))
+ (assert (or read write)
+ (read write)
+ "Open not for reading nor writing.")
+ (let* ((flags (compute-flags read write append non-blocking create))
+ (fd (fcntl:open pathname flags (or create 0)))
+ (class (compute-class read write)))
+ (make-instance class
+ :fd fd
+ :input-buffer-size input-buffer-size
+ :output-buffer-size output-buffer-size)))
diff --git a/unistd-stream.asd b/unistd-stream.asd
index be1414f..47d9d69 100644
--- a/unistd-stream.asd
+++ b/unistd-stream.asd
@@ -33,4 +33,9 @@
"cl-stream")
:components
((:file "package")
- (:file "unistd-stream" :depends-on ("package"))))
+ (:file "unistd-input-stream" :depends-on ("unistd-stream"))
+ (:file "unistd-io-stream" :depends-on ("unistd-input-stream"
+ "unistd-output-stream"))
+ (:file "unistd-output-stream" :depends-on ("unistd-stream"))
+ (:file "unistd-stream" :depends-on ("package"))
+ (:file "unistd-stream-open" :depends-on ("unistd-io-stream"))))
diff --git a/unistd-stream.lisp b/unistd-stream.lisp
index 5fa8423..f65df73 100644
--- a/unistd-stream.lisp
+++ b/unistd-stream.lisp
@@ -58,108 +58,6 @@
(unistd:close (stream-fd stream))
(call-next-method))
-(defclass unistd-input-stream (unistd-stream buffered-input-stream)
- ()
- (:documentation "A buffered input stream using UNISTD:READ."))
-
-(defmethod make-stream-input-buffer ((stream unistd-input-stream))
- (cffi:foreign-alloc :unsigned-char
- :count (stream-input-buffer-size stream)))
-
-(defmethod discard-stream-input-buffer ((stream unistd-input-stream))
- (cffi:foreign-free (stream-input-buffer stream))
- (setf (stream-input-buffer stream) nil))
-
-(defmethod stream-fill-input-buffer ((stream unistd-input-stream))
- (let* ((buffer (stream-input-buffer stream))
- (length (stream-input-length stream))
- (fd (stream-fd stream))
- (buf (cffi:mem-aptr buffer :unsigned-char length))
- (buflen (- (stream-input-buffer-size stream) length))
- (r (if (stream-blocking-p stream)
- (unistd:read fd buf buflen)
- (unistd:read-non-blocking fd buf buflen))))
- (cond ((eq :non-blocking r)
- :non-blocking)
- ((= r 0)
- :eof)
- ((< r 0)
- (error 'stream-input-error :stream stream))
- (t
- (incf (stream-input-length stream) r)
- nil))))
-
-(defmethod stream-read-element-from-buffer ((stream unistd-input-stream))
- (let ((element (cffi:mem-aref (stream-input-buffer stream) :unsigned-char
- (stream-input-index stream))))
- (incf (stream-input-index stream))
- (values element nil)))
-
-(defun unistd-input-stream (fd)
- "Creates a buffered input stream for file descriptor FD."
- (make-instance 'unistd-input-stream :fd fd))
-
-(defclass unistd-output-stream (unistd-stream buffered-output-stream)
- ()
- (:documentation "A buffered output stream using UNISTD:WRITE."))
-
-(defmethod make-stream-output-buffer ((stream unistd-output-stream))
- (cffi:foreign-alloc :unsigned-char
- :count (stream-output-buffer-size stream)))
-
-(defmethod discard-stream-output-buffer ((stream unistd-output-stream))
- (cffi:foreign-free (stream-output-buffer stream))
- (setf (stream-output-buffer stream) nil))
-
-(defmethod stream-flush-output-buffer ((stream unistd-output-stream))
- (let ((buffer (stream-output-buffer stream)))
- (let* ((fd (stream-fd stream))
- (index (stream-output-index stream))
- (buf (cffi:mem-aptr buffer :unsigned-char index))
- (buflen (- (stream-output-length stream) index))
- (r (if (stream-blocking-p stream)
- (unistd:write fd buf buflen)
- (unistd:write-non-blocking fd buf buflen))))
- (cond ((eq :non-blocking r)
- :non-blocking)
- ((= 0 r)
- :eof)
- ((< r 0)
- (error 'stream-output-error :stream stream))
- (t
- (incf (stream-output-index stream) r)
- (when (= (stream-output-index stream)
- (stream-output-length stream))
- (setf (stream-output-index stream) 0
- (stream-output-length stream) 0))
- nil)))))
-
-(defmethod stream-write-element-to-buffer ((stream unistd-output-stream)
- element)
- (setf (cffi:mem-aref (stream-output-buffer stream) :unsigned-char
- (stream-output-length stream))
- element)
- (incf (stream-output-length stream))
- nil)
-
-(defun unistd-output-stream (fd)
- "Creates a buffered output stream for file descriptor FD."
- (make-instance 'unistd-output-stream :fd fd))
-
-(defclass unistd-io-stream (unistd-input-stream unistd-output-stream)
- ()
- (:documentation "A buffered input/output stream using
-UNISTD:READ and UNISTD:WRITE."))
-
-(defmethod stream-close ((stream unistd-io-stream))
- (call-next-method)
- (cffi:foreign-free (stream-input-buffer stream))
- (cffi:foreign-free (stream-output-buffer stream)))
-
-(defun unistd-io-stream (fd)
- "Creates a buffered input/output stream for file descriptor FD."
- (make-instance 'unistd-io-stream :fd fd))
-
(defun compute-flags (read write append non-blocking create)
(logior (if append fcntl:+o-append+ 0)
(if non-blocking fcntl:+o-nonblock+ 0)