1 /**
2 * D header file to interface with the
3 * $(HTTP pubs.opengroup.org/onlinepubs/9699919799/basedefs/aio.h.html, Posix AIO API).
4 *
5 * Copyright: Copyright D Language Foundation 2018.
6 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7 * Authors: $(HTTPS github.com/darredevil, Alexandru Razvan Caciulescu)
8 */
9 module core.sys.posix.aio;
10
11 import core.sys.posix.signal;
12 import core.sys.posix.sys.types;
13
14 version (OSX)
15 version = Darwin;
16 else version (iOS)
17 version = Darwin;
18 else version (TVOS)
19 version = Darwin;
20 else version (WatchOS)
21 version = Darwin;
22
version(Posix)23 version (Posix):
24
25 extern (C):
26 @system:
27 @nogc:
28 nothrow:
29
30 version (CRuntime_Glibc)
31 {
32 import core.sys.posix.config;
33
34 struct aiocb
35 {
36 int aio_fildes;
37 int aio_lio_opcode;
38 int aio_reqprio;
39 void* aio_buf; //volatile
40 size_t aio_nbytes;
41 sigevent aio_sigevent;
42
43 aiocb* __next_prio;
44 int __abs_prio;
45 int __policy;
46 int __error_code;
47 ssize_t __return_value;
48
49 off_t aio_offset;
50 ubyte[32] __glibc_reserved;
51 }
52
53 static if (__USE_LARGEFILE64)
54 {
55 struct aiocb64
56 {
57 int aio_fildes;
58 int aio_lio_opcode;
59 int aio_reqprio;
60 void* aio_buf; //volatile
61 size_t aio_nbytes;
62 sigevent aio_sigevent;
63
64 aiocb* __next_prio;
65 int __abs_prio;
66 int __policy;
67 int __error_code;
68 ssize_t __return_value;
69
70 off_t aio_offset;
71 ubyte[32] __glibc_reserved;
72 }
73 }
74 }
75 else version (CRuntime_Bionic)
76 {
77 // Bionic does not define aiocb.
78 }
79 else version (CRuntime_Musl)
80 {
81 // https://git.musl-libc.org/cgit/musl/tree/include/aio.h
82 struct aiocb
83 {
84 int aio_fildes;
85 int aio_lio_opcode;
86 int aio_reqprio;
87 void* aio_buf; //volatile
88 size_t aio_nbytes;
89 sigevent aio_sigevent;
90 void* __td;
91 int[2] __lock;
92 int __err; //volatile
93 ssize_t __ret;
94 off_t aio_offset;
95 void* __next;
96 void* __prev;
97 ubyte[32-2*(void*).sizeof] __dummy4;
98 }
99 }
100 else version (CRuntime_UClibc)
101 {
102 import core.sys.posix.config;
103 import core.sys.posix.sys.types;
104
105 struct aiocb
106 {
107 int aio_fildes;
108 int aio_lio_opcode;
109 int aio_reqprio;
110 void* aio_buf; //volatile
111 size_t aio_nbytes;
112 sigevent aio_sigevent;
113
114 aiocb* __next_prio;
115 int __abs_prio;
116 int __policy;
117 int __error_code;
118 ssize_t __return_value;
119
120 static if (__USE_LARGEFILE64)
121 {
122 off_t aio_offset;
123 ubyte[off64_t.sizeof - off_t.sizeof] __pad;
124 }
125 else
126 {
127 off64_t aio_offset;
128 }
129 ubyte[32] __unused;
130 }
131
132 static if (__USE_LARGEFILE64)
133 {
134 struct aiocb64
135 {
136 int aio_fildes;
137 int aio_lio_opcode;
138 int aio_reqprio;
139 void* aio_buf; //volatile
140 size_t aio_nbytes;
141 sigevent aio_sigevent;
142
143 aiocb* __next_prio;
144 int __abs_prio;
145 int __policy;
146 int __error_code;
147 ssize_t __return_value;
148
149 off64_t aio_offset;
150 ubyte[32] __unused;
151 }
152 }
153 }
154 else version (Darwin)
155 {
156 struct aiocb
157 {
158 int aio_filedes;
159 off_t aio_offset;
160 void* aio_buf; // volatile
161 size_t aio_nbytes;
162 int reqprio;
163 sigevent aio_sigevent;
164 int aio_lio_opcode;
165 }
166 }
167 else version (FreeBSD)
168 {
169 struct __aiocb_private
170 {
171 long status;
172 long error;
173 void* kernelinfo;
174 }
175
176 struct aiocb
177 {
178 int aio_fildes;
179 off_t aio_offset;
180 void* aio_buf; // volatile
181 size_t aio_nbytes;
182 private int[2] __spare;
183 private void* _spare2__;
184 int aio_lio_opcode;
185 int aio_reqprio;
186 private __aiocb_private _aiocb_private;
187 sigevent aio_sigevent;
188 }
189
190 version = BSD_Posix;
191 }
192 else version (NetBSD)
193 {
194 struct aiocb
195 {
196 off_t aio_offset;
197 void* aio_buf; // volatile
198 size_t aio_nbytes;
199 int aio_fildes;
200 int aio_lio_opcode;
201 int aio_reqprio;
202 sigevent aio_sigevent;
203 private int _state;
204 private int _errno;
205 private ssize_t _retval;
206 }
207
208 version = BSD_Posix;
209 }
210 else version (OpenBSD)
211 {
212 // OpenBSD does not define aiocb.
213 }
214 else version (DragonFlyBSD)
215 {
216 struct aiocb
217 {
218 int aio_fildes;
219 off_t aio_offset;
220 void* aio_buf; // volatile
221 size_t aio_nbytes;
222 sigevent aio_sigevent;
223 int aio_lio_opcode;
224 int aio_reqprio;
225 private int _aio_val;
226 private int _aio_err;
227 }
228
229 version = BSD_Posix;
230 }
231 else version (Solaris)
232 {
233 struct aio_result_t
234 {
235 ssize_t aio_return;
236 int aio_errno;
237 }
238
239 struct aiocb
240 {
241 int aio_fildes;
242 void* aio_buf; // volatile
243 size_t aio_nbytes;
244 off_t aio_offset;
245 int aio_reqprio;
246 sigevent aio_sigevent;
247 int aio_lio_opcode;
248 aio_result_t aio_resultp;
249 int aio_state;
250 int[1] aio__pad;
251 }
252 }
253 else
254 static assert(false, "Unsupported platform");
255
256 /* Return values of cancelation function. */
257 version (CRuntime_Glibc)
258 {
259 enum
260 {
261 AIO_CANCELED,
262 AIO_NOTCANCELED,
263 AIO_ALLDONE
264 }
265 }
266 else version (CRuntime_Musl)
267 {
268 enum
269 {
270 AIO_CANCELED,
271 AIO_NOTCANCELED,
272 AIO_ALLDONE
273 }
274 }
275 else version (CRuntime_UClibc)
276 {
277 enum
278 {
279 AIO_CANCELED,
280 AIO_NOTCANCELED,
281 AIO_ALLDONE
282 }
283 }
284 else version (Darwin)
285 {
286 enum
287 {
288 AIO_ALLDONE = 0x1,
289 AIO_CANCELED = 0x2,
290 AIO_NOTCANCELED = 0x4,
291 }
292 }
293 else version (Solaris)
294 {
295 enum
296 {
297 AIO_CANCELED,
298 AIO_ALLDONE,
299 AIO_NOTCANCELED
300 }
301 }
302 else version (BSD_Posix)
303 {
304 enum
305 {
306 AIO_CANCELED,
307 AIO_NOTCANCELED,
308 AIO_ALLDONE
309 }
310 }
311
312 /* Operation codes for `aio_lio_opcode'. */
313 version (CRuntime_Glibc)
314 {
315 enum
316 {
317 LIO_READ,
318 LIO_WRITE,
319 LIO_NOP
320 }
321 }
322 else version (CRuntime_Musl)
323 {
324 enum
325 {
326 LIO_READ,
327 LIO_WRITE,
328 LIO_NOP
329 }
330 }
331 else version (CRuntime_UClibc)
332 {
333 enum
334 {
335 LIO_READ,
336 LIO_WRITE,
337 LIO_NOP
338 }
339 }
340 else version (Darwin)
341 {
342 enum
343 {
344 LIO_NOP = 0x0,
345 LIO_READ = 0x1,
346 LIO_WRITE = 0x2,
347 }
348 }
349 else version (Solaris)
350 {
351 enum
352 {
353 LIO_NOP,
354 LIO_READ,
355 LIO_WRITE,
356 }
357 }
358 else version (BSD_Posix)
359 {
360 enum
361 {
362 LIO_NOP,
363 LIO_WRITE,
364 LIO_READ
365 }
366 }
367
368 /* Synchronization options for `lio_listio' function. */
369 version (CRuntime_Glibc)
370 {
371 enum
372 {
373 LIO_WAIT,
374 LIO_NOWAIT
375 }
376 }
377 else version (CRuntime_Musl)
378 {
379 enum
380 {
381 LIO_WAIT,
382 LIO_NOWAIT
383 }
384 }
385 else version (CRuntime_UClibc)
386 {
387 enum
388 {
389 LIO_WAIT,
390 LIO_NOWAIT
391 }
392 }
393 else version (Darwin)
394 {
395 enum
396 {
397 LIO_NOWAIT = 0x1,
398 LIO_WAIT = 0x2,
399 }
400 }
401 else version (Solaris)
402 {
403 enum
404 {
405 LIO_NOWAIT,
406 LIO_WAIT
407 }
408 }
409 else version (BSD_Posix)
410 {
411 enum
412 {
413 LIO_NOWAIT,
414 LIO_WAIT
415 }
416 }
417
418 /* Functions implementing POSIX AIO. */
419 version (CRuntime_Glibc)
420 {
421 static if (__USE_LARGEFILE64)
422 {
423 int aio_read64(aiocb64* aiocbp);
424 int aio_write64(aiocb64* aiocbp);
425 int aio_fsync64(int op, aiocb64* aiocbp);
426 int aio_error64(const(aiocb64)* aiocbp);
427 ssize_t aio_return64(aiocb64* aiocbp);
428 int aio_suspend64(const(aiocb64*)* aiocb_list, int nitems, const(timespec)* timeout);
429 int aio_cancel64(int fd, aiocb64* aiocbp);
430 int lio_listio64(int mode, const(aiocb64*)* aiocb_list, int nitems, sigevent* sevp);
431
432 alias aio_read = aio_read64;
433 alias aio_write = aio_write64;
434 alias aio_fsync = aio_fsync64;
435 alias aio_error = aio_error64;
436 alias aio_return = aio_return64;
437 alias aio_suspend = aio_suspend64;
438 alias aio_cancel = aio_cancel64;
439 alias lio_listio = lio_listio64;
440 }
441 else
442 {
443 int aio_read(aiocb* aiocbp);
444 int aio_write(aiocb* aiocbp);
445 int aio_fsync(int op, aiocb* aiocbp);
446 int aio_error(const(aiocb)* aiocbp);
447 ssize_t aio_return(aiocb* aiocbp);
448 int aio_suspend(const(aiocb*)* aiocb_list, int nitems, const(timespec)* timeout);
449 int aio_cancel(int fd, aiocb* aiocbp);
450 int lio_listio(int mode, const(aiocb*)* aiocb_list, int nitems, sigevent* sevp);
451 }
452 }
453 else version (CRuntime_Bionic)
454 {
455 // Bionic does not implement aio.h
456 }
457 else version (CRuntime_UClibc)
458 {
459 static if (__USE_LARGEFILE64)
460 {
461 int aio_read64(aiocb64* aiocbp);
462 int aio_write64(aiocb64* aiocbp);
463 int aio_fsync64(int op, aiocb64* aiocbp);
464 int aio_error64(const(aiocb64)* aiocbp);
465 ssize_t aio_return64(aiocb64* aiocbp);
466 int aio_suspend64(const(aiocb64*)* aiocb_list, int nitems, const(timespec)* timeout);
467 int aio_cancel64(int fd, aiocb64* aiocbp);
468 int lio_listio64(int mode, const(aiocb64*)* aiocb_list, int nitems, sigevent* sevp);
469
470 alias aio_read = aio_read64;
471 alias aio_write = aio_write64;
472 alias aio_fsync = aio_fsync64;
473 alias aio_error = aio_error64;
474 alias aio_return = aio_return64;
475 alias aio_suspend = aio_suspend64;
476 alias aio_cancel = aio_cancel64;
477 alias lio_listio = lio_listio64;
478 }
479 else
480 {
481 int aio_read(aiocb* aiocbp);
482 int aio_write(aiocb* aiocbp);
483 int aio_fsync(int op, aiocb* aiocbp);
484 int aio_error(const(aiocb)* aiocbp);
485 ssize_t aio_return(aiocb* aiocbp);
486 int aio_suspend(const(aiocb*)* aiocb_list, int nitems, const(timespec)* timeout);
487 int aio_cancel(int fd, aiocb* aiocbp);
488 int lio_listio(int mode, const(aiocb*)* aiocb_list, int nitems, sigevent* sevp);
489 }
490 }
491 else version (OpenBSD)
492 {
493 // OpenBSD does not implement aio.h
494 }
495 else
496 {
497 int aio_read(aiocb* aiocbp);
498 int aio_write(aiocb* aiocbp);
499 int aio_fsync(int op, aiocb* aiocbp);
500 int aio_error(const(aiocb)* aiocbp);
501 ssize_t aio_return(aiocb* aiocbp);
502 int aio_suspend(const(aiocb*)* aiocb_list, int nitems, const(timespec)* timeout);
503 int aio_cancel(int fd, aiocb* aiocbp);
504 int lio_listio(int mode, const(aiocb*)* aiocb_list, int nitems, sigevent* sevp);
505 }
506
507 /* Functions outside/extending POSIX requirement. */
508 version (CRuntime_Glibc)
509 {
510 static if (__USE_GNU)
511 {
512 /* To customize the implementation one can use the following struct. */
513 struct aioinit
514 {
515 int aio_threads;
516 int aio_num;
517 int aio_locks;
518 int aio_usedba;
519 int aio_debug;
520 int aio_numusers;
521 int aio_idle_time;
522 int aio_reserved;
523 }
524
525 void aio_init(const(aioinit)* init);
526 }
527 }
528 else version (CRuntime_UClibc)
529 {
530 static if (__USE_GNU)
531 {
532 /* To customize the implementation one can use the following struct. */
533 struct aioinit
534 {
535 int aio_threads;
536 int aio_num;
537 int aio_locks;
538 int aio_usedba;
539 int aio_debug;
540 int aio_numusers;
541 int aio_idle_time;
542 int aio_reserved;
543 }
544
545 void aio_init(const(aioinit)* init);
546 }
547 }
548 else version (FreeBSD)
549 {
550 int aio_waitcomplete(aiocb** aiocb_list, const(timespec)* timeout);
551 int aio_mlock(aiocb* aiocbp);
552 }
553 else version (DragonFlyBSD)
554 {
555 int aio_waitcomplete(aiocb** aiocb_list, const(timespec)* timeout);
556 }
557