1 /******************************************************************************
2 3 Simple POSIX I/O device interfaces and base classes, significantly
4 influenced by Tango's Conduit.
5 6 An input device is merely an ISelectable (a file descriptor) with a read()
7 method and an output an ISelectable device wih a write() method. read() and
8 write() wrap the POSIX function with the same name.
9 10 Copyright:
11 Copyright (c) 2009-2016 dunnhumby Germany GmbH.
12 All rights reserved.
13 14 License:
15 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
16 Alternatively, this file may be distributed under the terms of the Tango
17 3-Clause BSD License (see LICENSE_BSD.txt for details).
18 19 ******************************************************************************/20 21 moduleocean.io.device.IODevice;
22 23 24 importocean.meta.types.Qualifiers;
25 26 importocean.io.model.IConduit: ISelectable;
27 28 importcore.sys.posix.unistd: read, write;
29 importcore.sys.posix.sys.types: ssize_t;
30 31 /******************************************************************************
32 33 Input device interface
34 35 ******************************************************************************/36 37 interfaceIInputDevice : ISelectable38 {
39 /**************************************************************************
40 41 Convenience type alias for subclasses/interfaces
42 43 **************************************************************************/44 45 alias .ssize_tssize_t;
46 47 /**************************************************************************
48 49 read() attempts to read up to dst.length bytes from the device
50 associated with the file descriptor of this instance into dst.
51 52 If dst.length is zero, read() returns zero and has no other results. If
53 count is greater than SSIZE_MAX, the result is unspecified.
54 55 Params:
56 dst = destination buffer
57 58 Returns:
59 On success, the number of bytes read is returned (zero indicates end
60 of file), and the file position is advanced by this number. It is
61 not an error if this number is smaller than the number of bytes
62 requested; this may happen for example because fewer bytes are actu‐
63 ally available right now (maybe because we were close to end-of-
64 file, or because we are reading from a pipe, or from a terminal), or
65 because read() was interrupted by a signal. On error, -1 is
66 returned, and errno is set appropriately. In this case it is left
67 unspecified whether the file position (if any) changes.
68 69 Errors:
70 71 EAGAIN The file descriptor fd refers to a file other than a socket
72 and has been marked nonblocking (O_NONBLOCK), and the read
73 would block.
74 75 EAGAIN or EWOULDBLOCK
76 The file descriptor fd refers to a socket and has been marked
77 nonblocking (O_NONBLOCK), and the read would block.
78 POSIX.1-2001 allows either error to be returned for this
79 case, and does not require these constants to have the same
80 value, so a portable application should check for both possi‐
81 bilities.
82 83 EBADF fd is not a valid file descriptor or is not open for reading.
84 85 EFAULT dst is outside your accessible address space.
86 87 EINTR The call was interrupted by a signal before any data was
88 read; see signal(7).
89 90 EINVAL fd is attached to an object which is unsuitable for reading;
91 or the file was opened with the O_DIRECT flag, and either the
92 address specified in dst, the value specified in count, or
93 the current file offset is not suitably aligned.
94 95 EINVAL fd was created via a call to timerfd_create(2) and the wrong
96 size buffer was given to read(); see timerfd_create(2) for
97 further information.
98 99 EIO I/O error. This will happen for example when the process is
100 in a background process group, tries to read from its con‐
101 trolling tty, and either it is ignoring or blocking SIGTTIN
102 or its process group is orphaned. It may also occur when
103 there is a low-level I/O error while reading from a disk or
104 tape.
105 106 EISDIR fd refers to a directory.
107 108 Other errors may occur, depending on the object connected to fd.
109 POSIX allows a read() that is interrupted after reading some data to
110 return -1 (with errno set to EINTR) or to return the number of bytes
111 already read.
112 113 **************************************************************************/114 115 ssize_tread ( void[] dst );
116 }
117 118 /******************************************************************************
119 120 Output device interface
121 122 ******************************************************************************/123 124 interfaceIOutputDevice : ISelectable125 {
126 /**************************************************************************
127 128 Convenience type alias for subclasses/interfaces
129 130 **************************************************************************/131 132 alias .ssize_tssize_t;
133 134 /**************************************************************************
135 136 write() writes up to count bytes from the buffer pointed buf to the file
137 referred to by the file descriptor fd.
138 139 The number of bytes written may be less than count if, for example,
140 there is insufficient space on the underlying physical medium, or the
141 RLIMIT_FSIZE resource limit is encountered (see setrlimit(2)), or the
142 call was interrupted by a signal handler after having written less than
143 count bytes. (See also pipe(7).)
144 145 For a seekable file (i.e., one to which lseek(2) may be applied, for
146 example, a regular file) writing takes place at the current file offset,
147 and the file offset is incremented by the number of bytes actually writ‐
148 ten. If the file was open(2)ed with O_APPEND, the file offset is first
149 set to the end of the file before writing. The adjustment of the file
150 offset and the write operation are performed as an atomic step.
151 152 POSIX requires that a read(2) which can be proved to occur after a
153 write() has returned returns the new data. Note that not all file sys‐
154 tems are POSIX conforming.
155 156 Returns:
157 On success, the number of bytes written is returned (zero indicates
158 nothing was written). On error, -1 is returned, and errno is set
159 appropriately.
160 161 If count is zero and fd refers to a regular file, then write() may
162 return a failure status if one of the errors below is detected. If
163 no errors are detected, 0 will be returned without causing any other
164 effect. If count is zero and fd refers to a file other than a regu‐
165 lar file, the results are not specified.
166 167 168 write() writes up to count bytes from the buffer pointed buf to the
169 file referred to by the file descriptor fd.
170 171 The number of bytes written may be less than count if, for example,
172 there is insufficient space on the underlying physical medium, or
173 the RLIMIT_FSIZE resource limit is encountered (see setrlimit(2)),
174 or the call was interrupted by a signal handler after having written
175 less than count bytes. (See also pipe(7).)
176 177 For a seekable file (i.e., one to which lseek(2) may be applied, for
178 example, a regular file) writing takes place at the current file
179 offset, and the file offset is incremented by the number of bytes
180 actually written. If the file was open(2)ed with O_APPEND, the file
181 offset is first set to the end of the file before writing. The
182 adjustment of the file offset and the write operation are performed
183 as an atomic step.
184 185 POSIX requires that a read(2) which can be proved to occur after a
186 write() has returned returns the new data. Note that not all file
187 systems are POSIX conforming.
188 189 Errors:
190 EAGAIN The file descriptor fd refers to a file other than a socket
191 and has been marked nonblocking (O_NONBLOCK), and the write
192 would block.
193 194 EAGAIN or EWOULDBLOCK
195 The file descriptor fd refers to a socket and has been marked
196 nonblocking (O_NONBLOCK), and the write would block.
197 POSIX.1-2001 allows either error to be returned for this
198 case, and does not require these constants to have the same
199 value, so a portable application should check for both possi‐
200 bilities.
201 202 EBADF fd is not a valid file descriptor or is not open for writing.
203 204 EDESTADDRREQ
205 fd refers to a datagram socket for which a peer address has
206 not been set using connect(2).
207 208 EFAULT buf is outside your accessible address space.
209 210 EFBIG An attempt was made to write a file that exceeds the imple‐
211 mentation-defined maximum file size or the process's file
212 size limit, or to write at a position past the maximum
213 allowed offset.
214 215 EINTR The call was interrupted by a signal before any data was
216 written; see signal(7).
217 218 EINVAL fd is attached to an object which is unsuitable for writing;
219 or the file was opened with the O_DIRECT flag, and either the
220 address specified in buf, the value specified in count, or
221 the current file offset is not suitably aligned.
222 223 EIO A low-level I/O error occurred while modifying the inode.
224 225 ENOSPC The device containing the file referred to by fd has no room
226 for the data.
227 228 EPIPE fd is connected to a pipe or socket whose reading end is
229 closed. When this happens the writing process will also
230 receive a SIGPIPE signal. (Thus, the write return value is
231 seen only if the program catches, blocks or ignores this sig‐
232 nal.)
233 234 Other errors may occur, depending on the object connected to fd.
235 236 **************************************************************************/237 238 ssize_twrite ( const(void)[] dst );
239 }
240 241 /******************************************************************************
242 243 Input device base class, may be used to conveniently implement an
244 IInputDevice.
245 246 ******************************************************************************/247 248 abstractclassInputDevice : IInputDevice249 {
250 /**************************************************************************
251 252 Attempts to read dst.length bytes, see IInputDevice.read()
253 documentation.
254 255 Params:
256 dst = destination data buffer
257 258 Returns
259 the number of bytes read and stored in dst on success, 0 on end-of-
260 file condition or -1 on error. On error errno is set appropriately.
261 262 **************************************************************************/263 264 publicssize_tread ( void[] dst )
265 {
266 return .read(this.fileHandle(), dst.ptr, dst.length);
267 }
268 }
269 270 /******************************************************************************
271 272 IODevice device base class, may be used to conveniently implement an I/O
273 class that is both an IInputDevice and IOutputDevice.
274 275 ******************************************************************************/276 277 abstractclassIODevice : InputDevice, IOutputDevice278 {
279 /**************************************************************************
280 281 Attempts to write src.length bytes, see IOutputDevice.write()
282 documentation.
283 284 Params:
285 src = source data buffer
286 287 Returns
288 the number of bytes written on success or -1 on error. On error
289 errno is set appropriately.
290 291 **************************************************************************/292 293 abstractpublicssize_twrite ( const(void)[] src );
294 }