1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; indent-tabs-mode: nil -*-
3 ;;; --- Common functions.
6 (in-package :io.zeta-streams
)
8 ;;;-----------------------------------------------------------------------------
9 ;;; Get and Set O_NONBLOCK
10 ;;;-----------------------------------------------------------------------------
12 (defun %get-fd-nonblock-mode
(fd)
13 (let ((current-flags (nix:fcntl fd nix
:f-getfl
)))
14 (logtest nix
:o-nonblock current-flags
)))
16 (defun %set-fd-nonblock-mode
(fd mode
)
17 (let* ((current-flags (nix:fcntl fd nix
:f-getfl
))
19 (logior current-flags nix
:o-nonblock
)
20 (logandc2 current-flags nix
:o-nonblock
))))
21 (when (/= new-flags current-flags
)
22 (nix:fcntl fd nix
:f-setfl new-flags
))
26 ;;;-----------------------------------------------------------------------------
27 ;;; Default DEVICE-READ
28 ;;;-----------------------------------------------------------------------------
30 (defmethod device-read ((device device
) buffer start end
&optional
(timeout nil timeoutp
))
31 (let ((timeout (if timeoutp timeout
(input-timeout-of device
)))
32 (nbytes (if (and timeout
(zerop timeout
))
33 (read-octets-non-blocking (input-handle-of device
) buffer start end
)
34 (read-octets-with-timeout (input-handle-of device
) buffer start end timeout
))))
35 (when (plusp nbytes
) (incf (device-position device
) nbytes
))
38 (defun read-octets-non-blocking (fd buffer start end
)
39 (declare (type unsigned-byte fd
)
40 (type ub8-sarray buffer
)
41 (type unsigned-byte start end
))
42 (with-pointer-to-vector-data (buf buffer
)
44 (nix:repeat-upon-eintr
45 (nix:read fd
(inc-pointer buf start
) (- end start
)))
46 (nix:ewouldblock
() 0)
48 (if (zerop nbytes
) :eof nbytes
)))))
50 (defun read-octets-with-timeout (fd buffer start end timeout
)
51 (declare (type unsigned-byte fd
)
52 (type ub8-sarray buffer
)
53 (type unsigned-byte start end
))
54 (with-pointer-to-vector-data (buf buffer
)
55 (nix:repeat-decreasing-timeout
(remaining timeout nil
)
56 (flet ((check-timeout ()
58 (iomux:wait-until-fd-ready fd
:input remaining
)
61 (nix:read fd
(inc-pointer buf start
) (- end start
))
62 (nix:eintr
() (check-timeout))
63 (nix:ewouldblock
() (check-timeout))
65 (if (zerop nbytes
) :eof nbytes
)))))))
68 ;;;-----------------------------------------------------------------------------
69 ;;; Default DEVICE-WRITE
70 ;;;-----------------------------------------------------------------------------
72 (defmethod device-write ((device device
) buffer start end
&optional
(timeout nil timeoutp
))
73 (let* ((timeout (if timeoutp timeout
(output-timeout-of device
)))
74 (nbytes (if (and timeout
(zerop timeout
))
75 (write-octets-non-blocking (output-handle-of device
) buffer start end
)
76 (write-octets-with-timeout (output-handle-of device
) buffer start end timeout
))))
77 (when (plusp nbytes
) (incf (device-position device
) nbytes
))
80 (defun write-octets-non-blocking (fd buffer start end
)
81 (declare (type unsigned-byte fd
)
82 (type ub8-sarray buffer
)
83 (type unsigned-byte start end
))
84 (with-pointer-to-vector-data (buf buffer
)
86 (osicat-posix:repeat-upon-eintr
87 (nix:write fd
(inc-pointer buf start
) (- end start
)))
88 (nix:ewouldblock
() 0)
90 (if (zerop nbytes
) :eof nbytes
)))))
92 (defun write-octets-with-timeout (fd buffer start end timeout
)
93 (declare (type unsigned-byte fd
)
94 (type ub8-sarray buffer
)
95 (type unsigned-byte start end
))
96 (with-pointer-to-vector-data (buf buffer
)
97 (nix:repeat-decreasing-timeout
(remaining timeout nil
)
98 (flet ((check-timeout ()
100 (iomux:wait-until-fd-ready fd
:output remaining
)
103 (nix:write fd
(inc-pointer buf start
) (- end start
))
104 (nix:eintr
() (check-timeout))
105 (nix:ewouldblock
() (check-timeout))
107 (return (if (zerop nbytes
) :eof nbytes
))))))))