2 * D header file for POSIX.
4 * Copyright: Copyright Sean Kelly 2005 - 2016.
5 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 * Authors: Sean Kelly, Alex Rønne Petersen
7 * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
9 module core.sys.posix.sys.select;
11 import core.sys.posix.config;
12 public import core.stdc.time; // for timespec
13 public import core.sys.posix.sys.time; // for timeval
14 public import core.sys.posix.sys.types; // for time_t
15 public import core.sys.posix.signal; // for sigset_t
17 //debug=select; // uncomment to turn on debugging printf's
25 else version (WatchOS)
29 extern (C) nothrow @nogc:
35 NOTE: This module requires timeval from core.sys.posix.sys.time, but timeval
36 is supposedly an XOpen extension. As a result, this header will not
37 compile on platforms that are not XSI-compliant. This must be resolved
38 on a per-platform basis.
42 void FD_CLR(int fd, fd_set* fdset);
43 int FD_ISSET(int fd, const(fd_set)* fdset);
44 void FD_SET(int fd, fd_set* fdset);
45 void FD_ZERO(fd_set* fdset);
49 int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
50 int select(int, fd_set*, fd_set*, fd_set*, timeval*);
53 version (CRuntime_Glibc)
57 alias c_long __fd_mask;
58 enum uint __NFDBITS = 8 * __fd_mask.sizeof;
60 extern (D) auto __FDELT( int d ) pure
65 extern (D) auto __FDMASK( int d ) pure
67 return cast(__fd_mask) 1 << ( d % __NFDBITS );
71 enum FD_SETSIZE = 1024;
75 __fd_mask[FD_SETSIZE / __NFDBITS] fds_bits;
78 extern (D) void FD_CLR( int fd, fd_set* fdset ) pure
80 fdset.fds_bits[__FDELT( fd )] &= ~__FDMASK( fd );
83 extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure
85 return (fdset.fds_bits[__FDELT( fd )] & __FDMASK( fd )) != 0;
88 extern (D) void FD_SET( int fd, fd_set* fdset ) pure
90 fdset.fds_bits[__FDELT( fd )] |= __FDMASK( fd );
93 extern (D) void FD_ZERO( fd_set* fdset ) pure
95 fdset.fds_bits[0 .. $] = 0;
99 + GNU ASM Implementation
101 # define __FD_ZERO(fdsp) \
104 __asm__ __volatile__ ("cld; rep; stosl" \
105 : "=c" (__d0), "=D" (__d1) \
106 : "a" (0), "0" (sizeof (fd_set) \
107 / sizeof (__fd_mask)), \
108 "1" (&__FDS_BITS (fdsp)[0]) \
112 # define __FD_SET(fd, fdsp) \
113 __asm__ __volatile__ ("btsl %1,%0" \
114 : "=m" (__FDS_BITS (fdsp)[__FDELT (fd)]) \
115 : "r" (((int) (fd)) % __NFDBITS) \
117 # define __FD_CLR(fd, fdsp) \
118 __asm__ __volatile__ ("btrl %1,%0" \
119 : "=m" (__FDS_BITS (fdsp)[__FDELT (fd)]) \
120 : "r" (((int) (fd)) % __NFDBITS) \
122 # define __FD_ISSET(fd, fdsp) \
124 ({register char __result; \
125 __asm__ __volatile__ ("btl %1,%2 ; setcb %b0" \
127 : "r" (((int) (fd)) % __NFDBITS), \
128 "m" (__FDS_BITS (fdsp)[__FDELT (fd)]) \
133 int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
134 int select(int, fd_set*, fd_set*, fd_set*, timeval*);
136 else version (Darwin)
140 enum uint __DARWIN_NBBY = 8; /* bits in a byte */
141 enum uint __DARWIN_NFDBITS = (int.sizeof * __DARWIN_NBBY); /* bits per mask */
144 enum FD_SETSIZE = 1024;
148 int[(FD_SETSIZE + (__DARWIN_NFDBITS - 1)) / __DARWIN_NFDBITS] fds_bits;
151 extern (D) void FD_CLR( int fd, fd_set* fdset ) pure
153 fdset.fds_bits[fd / __DARWIN_NFDBITS] &= ~(1 << (fd % __DARWIN_NFDBITS));
156 extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure
158 return (fdset.fds_bits[fd / __DARWIN_NFDBITS] & (1 << (fd % __DARWIN_NFDBITS))) != 0;
161 extern (D) void FD_SET( int fd, fd_set* fdset ) pure
163 fdset.fds_bits[fd / __DARWIN_NFDBITS] |= 1 << (fd % __DARWIN_NFDBITS);
166 extern (D) void FD_ZERO( fd_set* fdset ) pure
168 fdset.fds_bits[0 .. $] = 0;
171 int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
172 int select(int, fd_set*, fd_set*, fd_set*, timeval*);
174 else version (FreeBSD)
178 alias c_ulong __fd_mask;
179 enum _NFDBITS = __fd_mask.sizeof * 8;
182 enum uint FD_SETSIZE = 1024;
186 __fd_mask[(FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS] __fds_bits;
189 extern (D) __fd_mask __fdset_mask(uint n) pure
191 return cast(__fd_mask) 1 << (n % _NFDBITS);
194 extern (D) void FD_CLR( int n, fd_set* p ) pure
196 p.__fds_bits[n / _NFDBITS] &= ~__fdset_mask(n);
199 extern (D) bool FD_ISSET( int n, const(fd_set)* p ) pure
201 return (p.__fds_bits[n / _NFDBITS] & __fdset_mask(n)) != 0;
204 extern (D) void FD_SET( int n, fd_set* p ) pure
206 p.__fds_bits[n / _NFDBITS] |= __fdset_mask(n);
209 extern (D) void FD_ZERO( fd_set* p ) pure
215 _n = (FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS;
217 _p.__fds_bits[--_n] = 0;
220 int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
221 int select(int, fd_set*, fd_set*, fd_set*, timeval*);
223 else version (NetBSD)
227 alias c_ulong __fd_mask;
228 enum _NFDBITS = __fd_mask.sizeof * 8;
231 enum uint FD_SETSIZE = 256;
235 __fd_mask[(FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS] __fds_bits;
238 extern (D) __fd_mask __fdset_mask(uint n) pure
240 return cast(__fd_mask) 1 << (n % _NFDBITS);
243 extern (D) void FD_CLR( int n, fd_set* p ) pure
245 p.__fds_bits[n / _NFDBITS] &= ~__fdset_mask(n);
248 extern (D) bool FD_ISSET( int n, const(fd_set)* p ) pure
250 return (p.__fds_bits[n / _NFDBITS] & __fdset_mask(n)) != 0;
253 extern (D) void FD_SET( int n, fd_set* p ) pure
255 p.__fds_bits[n / _NFDBITS] |= __fdset_mask(n);
258 extern (D) void FD_ZERO( fd_set* p ) pure
264 _n = (FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS;
266 _p.__fds_bits[--_n] = 0;
269 int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
270 int select(int, fd_set*, fd_set*, fd_set*, timeval*);
272 else version (OpenBSD)
276 alias uint __fd_mask;
277 enum _NFDBITS = __fd_mask.sizeof * 8;
280 enum uint FD_SETSIZE = 1024;
284 __fd_mask[(FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS] __fds_bits;
287 extern (D) __fd_mask __fdset_mask(uint n) pure
289 return cast(__fd_mask) 1 << (n % _NFDBITS);
292 extern (D) void FD_CLR(int n, fd_set* p) pure
294 p.__fds_bits[n / _NFDBITS] &= ~__fdset_mask(n);
297 extern (D) bool FD_ISSET(int n, const(fd_set)* p) pure
299 return (p.__fds_bits[n / _NFDBITS] & __fdset_mask(n)) != 0;
302 extern (D) void FD_SET(int n, fd_set* p) pure
304 p.__fds_bits[n / _NFDBITS] |= __fdset_mask(n);
307 extern (D) void FD_ZERO(fd_set* p) pure
310 size_t _n = (FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS;
313 _p.__fds_bits[--_n] = 0;
316 int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
317 int select(int, fd_set*, fd_set*, fd_set*, timeval*);
319 else version (DragonFlyBSD)
323 alias c_ulong __fd_mask;
324 enum _NFDBITS = __fd_mask.sizeof * 8;
327 enum uint FD_SETSIZE = 1024;
331 __fd_mask[(FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS] __fds_bits;
334 extern (D) __fd_mask __fdset_mask(uint n) pure
336 return cast(__fd_mask) 1 << (n % _NFDBITS);
339 extern (D) void FD_CLR( int n, fd_set* p ) pure
341 p.__fds_bits[n / _NFDBITS] &= ~__fdset_mask(n);
344 extern (D) bool FD_ISSET( int n, const(fd_set)* p ) pure
346 return (p.__fds_bits[n / _NFDBITS] & __fdset_mask(n)) != 0;
349 extern (D) void FD_SET( int n, fd_set* p ) pure
351 p.__fds_bits[n / _NFDBITS] |= __fdset_mask(n);
354 extern (D) void FD_ZERO( fd_set* p ) pure
360 _n = (FD_SETSIZE + (_NFDBITS - 1)) / _NFDBITS;
362 _p.__fds_bits[--_n] = 0;
365 int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
366 int select(int, fd_set*, fd_set*, fd_set*, timeval*);
368 else version (Solaris)
372 alias c_long fds_mask;
375 enum FD_NFDBITS = fds_mask.sizeof * _NBBY;
379 enum uint FD_SETSIZE = 65536;
381 enum uint FD_SETSIZE = 1024;
385 c_long[(FD_SETSIZE + (FD_NFDBITS - 1)) / FD_NFDBITS] fds_bits;
388 extern (D) void FD_SET(int __n, fd_set* __p) pure
390 __p.fds_bits[__n / FD_NFDBITS] |= 1UL << (__n % FD_NFDBITS);
393 extern (D) void FD_CLR(int __n, fd_set* __p) pure
395 __p.fds_bits[__n / FD_NFDBITS] &= ~(1UL << (__n % FD_NFDBITS));
398 extern (D) bool FD_ISSET(int __n, const(fd_set)* __p) pure
400 return (__p.fds_bits[__n / FD_NFDBITS] & (1UL << (__n % FD_NFDBITS))) != 0;
403 extern (D) void FD_ZERO(fd_set* __p) pure
405 __p.fds_bits[0 .. $] = 0;
408 int select(int, fd_set*, fd_set*, fd_set*, timeval*);
409 int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
411 else version (CRuntime_Bionic)
415 alias c_ulong __fd_mask;
416 enum uint __NFDBITS = 8 * __fd_mask.sizeof;
418 extern (D) auto __FDELT( int d ) pure
420 return d / __NFDBITS;
423 extern (D) auto __FDMASK( int d ) pure
425 return cast(__fd_mask) 1 << ( d % __NFDBITS );
429 enum FD_SETSIZE = 1024;
433 __fd_mask[FD_SETSIZE / __NFDBITS] fds_bits;
436 // These functions are generated in assembly in bionic.
437 extern (D) void FD_CLR( int fd, fd_set* fdset ) pure
439 fdset.fds_bits[__FDELT( fd )] &= ~__FDMASK( fd );
442 extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure
444 return (fdset.fds_bits[__FDELT( fd )] & __FDMASK( fd )) != 0;
447 extern (D) void FD_SET( int fd, fd_set* fdset ) pure
449 fdset.fds_bits[__FDELT( fd )] |= __FDMASK( fd );
452 extern (D) void FD_ZERO( fd_set* fdset ) pure
454 fdset.fds_bits[0 .. $] = 0;
457 int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
458 int select(int, fd_set*, fd_set*, fd_set*, timeval*);
460 else version (CRuntime_Musl)
462 enum FD_SETSIZE = 1024;
468 enum uint __NFDBITS = 8 * fd_mask.sizeof;
470 extern (D) auto __FDELT( int d ) pure
472 return d / __NFDBITS;
475 extern (D) auto __FDMASK( int d ) pure
477 return cast(fd_mask) 1 << ( d % __NFDBITS );
482 ulong[FD_SETSIZE / 8 / long.sizeof] fds_bits;
485 extern (D) void FD_CLR( int fd, fd_set* fdset ) pure
487 fdset.fds_bits[__FDELT( fd )] &= ~__FDMASK( fd );
490 extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure
492 return (fdset.fds_bits[__FDELT( fd )] & __FDMASK( fd )) != 0;
495 extern (D) void FD_SET( int fd, fd_set* fdset ) pure
497 fdset.fds_bits[__FDELT( fd )] |= __FDMASK( fd );
500 extern (D) void FD_ZERO( fd_set* fdset ) pure
502 fdset.fds_bits[0 .. $] = 0;
504 pragma(mangle, muslRedirTime64Mangle!("pselect", "__pselect_time64"))
505 int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
506 pragma(mangle, muslRedirTime64Mangle!("select", "__select_time64"))
507 int select(int, fd_set*, fd_set*, fd_set*, timeval*);
509 else version (CRuntime_UClibc)
513 alias c_long __fd_mask;
514 enum uint __NFDBITS = 8 * __fd_mask.sizeof;
516 extern (D) auto __FDELT( int d ) pure
518 return d / __NFDBITS;
521 extern (D) auto __FDMASK( int d ) pure
523 return cast(__fd_mask) 1 << ( d % __NFDBITS );
527 enum FD_SETSIZE = 1024;
531 __fd_mask[FD_SETSIZE / __NFDBITS] fds_bits;
534 extern (D) void FD_CLR( int fd, fd_set* fdset ) pure
536 fdset.fds_bits[__FDELT( fd )] &= ~__FDMASK( fd );
539 extern (D) bool FD_ISSET( int fd, const(fd_set)* fdset ) pure
541 return (fdset.fds_bits[__FDELT( fd )] & __FDMASK( fd )) != 0;
544 extern (D) void FD_SET( int fd, fd_set* fdset ) pure
546 fdset.fds_bits[__FDELT( fd )] |= __FDMASK( fd );
549 extern (D) void FD_ZERO( fd_set* fdset ) pure
551 fdset.fds_bits[0 .. $] = 0;
554 int pselect(int, fd_set*, fd_set*, fd_set*, const scope timespec*, const scope sigset_t*);
555 int select(int, fd_set*, fd_set*, fd_set*, timeval*);
559 static assert(false, "Unsupported platform");
564 import core.stdc.stdio: printf;
566 debug(select) printf("core.sys.posix.sys.select unittest\n");
570 for (auto i = 0; i < FD_SETSIZE; i++)
572 assert(!FD_ISSET(i, &fd));
575 for (auto i = 0; i < FD_SETSIZE; i++)
581 for (auto i = 0; i < FD_SETSIZE; i++)
584 assert(FD_ISSET(i, &fd));
586 assert(!FD_ISSET(i, &fd));
589 for (auto i = 0; i < FD_SETSIZE; i++)
597 for (auto i = 0; i < FD_SETSIZE; i++)
600 assert(!FD_ISSET(i, &fd));
602 assert(FD_ISSET(i, &fd));
607 for (auto i = 0; i < FD_SETSIZE; i++)
609 assert(!FD_ISSET(i, &fd));