1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; indent-tabs-mode: nil -*-
3 ;;; --- Common functions.
6 (in-package :io.zeta-streams
)
8 ;;;-----------------------------------------------------------------------------
9 ;;; Default no-op methods
10 ;;;-----------------------------------------------------------------------------
12 (defmethod device-clear-input ((device device
))
15 (defmethod device-clear-output ((device device
))
18 (defmethod device-flush-output ((device device
) &optional timeout
)
19 (declare (ignore timeout
))
22 (defmethod device-position ((device device
))
25 (defmethod (setf device-position
) (position (device device
) &rest args
)
26 (declare (ignore position args
))
29 (defmethod device-length ((device device
))
33 ;;;-----------------------------------------------------------------------------
34 ;;; Get and Set O_NONBLOCK
35 ;;;-----------------------------------------------------------------------------
37 (defun %get-fd-nonblock-mode
(fd)
38 (let ((current-flags (nix:fcntl fd nix
:f-getfl
)))
39 (logtest nix
:o-nonblock current-flags
)))
41 (defun %set-fd-nonblock-mode
(fd mode
)
42 (let* ((current-flags (nix:fcntl fd nix
:f-getfl
))
44 (logior current-flags nix
:o-nonblock
)
45 (logandc2 current-flags nix
:o-nonblock
))))
46 (when (/= new-flags current-flags
)
47 (nix:fcntl fd nix
:f-setfl new-flags
))
51 ;;;-----------------------------------------------------------------------------
52 ;;; Default DEVICE-READ
53 ;;;-----------------------------------------------------------------------------
55 (defmethod device-read ((device device
) buffer start end
&optional
(timeout nil timeoutp
))
56 (when (= start end
) (return-from device-read
0))
57 (let* ((timeout (if timeoutp timeout
(input-timeout-of device
)))
58 (nbytes (if (and timeout
(zerop timeout
))
59 (read-octets-non-blocking (input-handle-of device
) buffer start end
)
60 (read-octets-with-timeout (input-handle-of device
) buffer start end timeout
))))
61 (when (plusp nbytes
) (incf (device-position device
) nbytes
))
64 (defun read-octets-non-blocking (fd buffer start end
)
65 (declare (type unsigned-byte fd
)
66 (type ub8-sarray buffer
)
67 (type unsigned-byte start end
))
68 (with-pointer-to-vector-data (buf buffer
)
70 (nix:repeat-upon-eintr
71 (nix:read fd
(inc-pointer buf start
) (- end start
)))
72 (nix:ewouldblock
() 0)
74 (if (zerop nbytes
) :eof nbytes
)))))
76 (defun read-octets-with-timeout (fd buffer start end timeout
)
77 (declare (type unsigned-byte fd
)
78 (type ub8-sarray buffer
)
79 (type unsigned-byte start end
))
80 (with-pointer-to-vector-data (buf buffer
)
81 (nix:repeat-decreasing-timeout
(remaining timeout nil
)
82 (flet ((check-timeout ()
84 (iomux:wait-until-fd-ready fd
:input remaining
)
87 (nix:read fd
(inc-pointer buf start
) (- end start
))
88 (nix:eintr
() (check-timeout))
89 (nix:ewouldblock
() (check-timeout))
91 (if (zerop nbytes
) :eof nbytes
)))))))
94 ;;;-----------------------------------------------------------------------------
95 ;;; Default DEVICE-WRITE
96 ;;;-----------------------------------------------------------------------------
98 (defmethod device-write ((device device
) buffer start end
&optional
(timeout nil timeoutp
))
99 (when (= start end
) (return-from device-write
0))
100 (let* ((timeout (if timeoutp timeout
(output-timeout-of device
)))
101 (nbytes (if (and timeout
(zerop timeout
))
102 (write-octets-non-blocking (output-handle-of device
) buffer start end
)
103 (write-octets-with-timeout (output-handle-of device
) buffer start end timeout
))))
104 (when (plusp nbytes
) (incf (device-position device
) nbytes
))
107 (defun write-octets-non-blocking (fd buffer start end
)
108 (declare (type unsigned-byte fd
)
109 (type ub8-sarray buffer
)
110 (type unsigned-byte start end
))
111 (with-pointer-to-vector-data (buf buffer
)
113 (osicat-posix:repeat-upon-eintr
114 (nix:write fd
(inc-pointer buf start
) (- end start
)))
115 (nix:ewouldblock
() 0)
117 (if (zerop nbytes
) :eof nbytes
)))))
119 (defun write-octets-with-timeout (fd buffer start end timeout
)
120 (declare (type unsigned-byte fd
)
121 (type ub8-sarray buffer
)
122 (type unsigned-byte start end
))
123 (with-pointer-to-vector-data (buf buffer
)
124 (nix:repeat-decreasing-timeout
(remaining timeout nil
)
125 (flet ((check-timeout ()
126 (if (plusp remaining
)
127 (iomux:wait-until-fd-ready fd
:output remaining
)
130 (nix:write fd
(inc-pointer buf start
) (- end start
))
131 (nix:eintr
() (check-timeout))
132 (nix:ewouldblock
() (check-timeout))
134 (return (if (zerop nbytes
) :eof nbytes
))))))))