sys_select.odin 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #+build linux, darwin, netbsd, openbsd, freebsd, haiku
  2. package posix
  3. import "base:intrinsics"
  4. import "core:c"
  5. when ODIN_OS == .Darwin {
  6. foreign import lib "system:System"
  7. } else {
  8. foreign import lib "system:c"
  9. }
  10. // sys/select.h - select types
  11. foreign lib {
  12. /*
  13. Examines the file descriptor sets to see whether some of their descriptors are ready for writing,
  14. or have an exceptional condition pending, respectively.
  15. Returns: -1 (setting errno) on failure, total amount of bits set in the bit masks otherwise
  16. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pselect.html ]]
  17. */
  18. @(link_name=LPSELECT)
  19. pselect :: proc(
  20. nfds: c.int,
  21. readfds: ^fd_set,
  22. writefds: ^fd_set,
  23. errorfds: ^fd_set,
  24. timeout: ^timespec,
  25. sigmask: ^sigset_t,
  26. ) -> c.int ---
  27. /*
  28. Equivalent to pselect() except a more specific timeout resolution (nanoseconds),
  29. does not have a signal mask, and may modify the timeout.
  30. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pselect.html ]]
  31. */
  32. @(link_name=LSELECT)
  33. select :: proc(
  34. nfds: c.int,
  35. readfds: ^fd_set,
  36. writefds: ^fd_set,
  37. errorfds: ^fd_set,
  38. timeout: ^timeval,
  39. ) -> c.int ---
  40. }
  41. when ODIN_OS == .NetBSD {
  42. LPSELECT :: "__pselect50"
  43. LSELECT :: "__select50"
  44. } else {
  45. LPSELECT :: "pselect"
  46. LSELECT :: "select"
  47. }
  48. when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux || ODIN_OS == .Haiku {
  49. suseconds_t :: distinct (c.int32_t when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .Haiku else c.long)
  50. timeval :: struct {
  51. tv_sec: time_t, /* [PSX] seconds */
  52. tv_usec: suseconds_t, /* [PSX] microseconds */
  53. }
  54. // Maximum number of file descriptors in the fd_set structure.
  55. FD_SETSIZE :: #config(POSIX_FD_SETSIZE, 256 when ODIN_OS == .NetBSD else 1024)
  56. @(private)
  57. __NFDBITS :: size_of(c.int32_t) * 8
  58. // NOTE: this seems correct for FreeBSD but they do use a set backed by the long type themselves (thus the align change).
  59. @(private)
  60. ALIGN :: align_of(c.long) when ODIN_OS == .FreeBSD || ODIN_OS == .Linux else align_of(c.int32_t)
  61. when ODIN_OS == .Haiku {
  62. fd_set :: struct #align(ALIGN) {
  63. fds_bits: [(FD_SETSIZE + (__NFDBITS - 1)) / __NFDBITS]c.int32_t,
  64. }
  65. } else {
  66. fd_set :: struct #align(ALIGN) {
  67. fds_bits: [(FD_SETSIZE / __NFDBITS) when (FD_SETSIZE % __NFDBITS) == 0 else (FD_SETSIZE / __NFDBITS) + 1]c.int32_t,
  68. }
  69. }
  70. @(private)
  71. __check_fd_set :: #force_inline proc "contextless" (_a: FD, _b: rawptr) -> bool {
  72. if _a < 0 {
  73. set_errno(.EINVAL)
  74. }
  75. if _a >= FD_SETSIZE {
  76. set_errno(.EINVAL)
  77. }
  78. return true
  79. }
  80. FD_CLR :: #force_inline proc "contextless" (_fd: FD, _p: ^fd_set) {
  81. if __check_fd_set(_fd, _p) {
  82. _p.fds_bits[cast(c.ulong)_fd / __NFDBITS] &= ~cast(c.int32_t)((cast(c.ulong)1) << (cast(c.ulong)_fd % __NFDBITS))
  83. }
  84. }
  85. FD_ISSET :: #force_inline proc "contextless" (_fd: FD, _p: ^fd_set) -> bool {
  86. if __check_fd_set(_fd, _p) {
  87. return bool(_p.fds_bits[cast(c.ulong)_fd / __NFDBITS] & cast(c.int32_t)((cast(c.ulong)1) << (cast(c.ulong)_fd % __NFDBITS)))
  88. }
  89. return false
  90. }
  91. FD_SET :: #force_inline proc "contextless" (_fd: FD, _p: ^fd_set) {
  92. if __check_fd_set(_fd, _p) {
  93. _p.fds_bits[cast(c.ulong)_fd / __NFDBITS] |= cast(c.int32_t)((cast(c.ulong)1) << (cast(c.ulong)_fd % __NFDBITS))
  94. }
  95. }
  96. FD_ZERO :: #force_inline proc "contextless" (_p: ^fd_set) {
  97. intrinsics.mem_zero(_p, size_of(fd_set))
  98. }
  99. }