| File: | include/sys/select.h |
| Warning: | line 95, column 10 Array access (via field 'fds_bits') results in a null pointer dereference |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | //===-- SelectHelper.cpp --------------------------------------------------===// | ||||
| 2 | // | ||||
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||
| 4 | // See https://llvm.org/LICENSE.txt for license information. | ||||
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||
| 6 | // | ||||
| 7 | //===----------------------------------------------------------------------===// | ||||
| 8 | |||||
| 9 | #if defined(__APPLE__) | ||||
| 10 | // Enable this special support for Apple builds where we can have unlimited | ||||
| 11 | // select bounds. We tried switching to poll() and kqueue and we were panicing | ||||
| 12 | // the kernel, so we have to stick with select for now. | ||||
| 13 | #define _DARWIN_UNLIMITED_SELECT | ||||
| 14 | #endif | ||||
| 15 | |||||
| 16 | #include "lldb/Utility/SelectHelper.h" | ||||
| 17 | #include "lldb/Utility/LLDBAssert.h" | ||||
| 18 | #include "lldb/Utility/Status.h" | ||||
| 19 | #include "lldb/lldb-enumerations.h" | ||||
| 20 | #include "lldb/lldb-types.h" | ||||
| 21 | |||||
| 22 | #include "llvm/ADT/DenseMap.h" | ||||
| 23 | |||||
| 24 | #include <algorithm> | ||||
| 25 | #include <chrono> | ||||
| 26 | #include <optional> | ||||
| 27 | |||||
| 28 | #include <cerrno> | ||||
| 29 | #if defined(_WIN32) | ||||
| 30 | // Define NOMINMAX to avoid macros that conflict with std::min and std::max | ||||
| 31 | #define NOMINMAX | ||||
| 32 | #include <winsock2.h> | ||||
| 33 | #else | ||||
| 34 | #include <sys/time.h> | ||||
| 35 | #include <sys/select.h> | ||||
| 36 | #endif | ||||
| 37 | |||||
| 38 | |||||
| 39 | SelectHelper::SelectHelper() | ||||
| 40 | : m_fd_map(), m_end_time() // Infinite timeout unless | ||||
| 41 | // SelectHelper::SetTimeout() gets called | ||||
| 42 | {} | ||||
| 43 | |||||
| 44 | void SelectHelper::SetTimeout(const std::chrono::microseconds &timeout) { | ||||
| 45 | using namespace std::chrono; | ||||
| 46 | m_end_time = steady_clock::time_point(steady_clock::now() + timeout); | ||||
| 47 | } | ||||
| 48 | |||||
| 49 | void SelectHelper::FDSetRead(lldb::socket_t fd) { | ||||
| 50 | m_fd_map[fd].read_set = true; | ||||
| 51 | } | ||||
| 52 | |||||
| 53 | void SelectHelper::FDSetWrite(lldb::socket_t fd) { | ||||
| 54 | m_fd_map[fd].write_set = true; | ||||
| 55 | } | ||||
| 56 | |||||
| 57 | void SelectHelper::FDSetError(lldb::socket_t fd) { | ||||
| 58 | m_fd_map[fd].error_set = true; | ||||
| 59 | } | ||||
| 60 | |||||
| 61 | bool SelectHelper::FDIsSetRead(lldb::socket_t fd) const { | ||||
| 62 | auto pos = m_fd_map.find(fd); | ||||
| 63 | if (pos != m_fd_map.end()) | ||||
| 64 | return pos->second.read_is_set; | ||||
| 65 | else | ||||
| 66 | return false; | ||||
| 67 | } | ||||
| 68 | |||||
| 69 | bool SelectHelper::FDIsSetWrite(lldb::socket_t fd) const { | ||||
| 70 | auto pos = m_fd_map.find(fd); | ||||
| 71 | if (pos != m_fd_map.end()) | ||||
| 72 | return pos->second.write_is_set; | ||||
| 73 | else | ||||
| 74 | return false; | ||||
| 75 | } | ||||
| 76 | |||||
| 77 | bool SelectHelper::FDIsSetError(lldb::socket_t fd) const { | ||||
| 78 | auto pos = m_fd_map.find(fd); | ||||
| 79 | if (pos != m_fd_map.end()) | ||||
| 80 | return pos->second.error_is_set; | ||||
| 81 | else | ||||
| 82 | return false; | ||||
| 83 | } | ||||
| 84 | |||||
| 85 | static void updateMaxFd(std::optional<lldb::socket_t> &vold, | ||||
| 86 | lldb::socket_t vnew) { | ||||
| 87 | if (!vold) | ||||
| 88 | vold = vnew; | ||||
| 89 | else | ||||
| 90 | vold = std::max(*vold, vnew); | ||||
| 91 | } | ||||
| 92 | |||||
| 93 | lldb_private::Status SelectHelper::Select() { | ||||
| 94 | lldb_private::Status error; | ||||
| 95 | #ifdef _WIN32 | ||||
| 96 | // On windows FD_SETSIZE limits the number of file descriptors, not their | ||||
| 97 | // numeric value. | ||||
| 98 | lldbassert(m_fd_map.size() <= FD_SETSIZE)lldb_private::lldb_assert(static_cast<bool>(m_fd_map.size () <= 1024), "m_fd_map.size() <= FD_SETSIZE", __FUNCTION__ , "/usr/src/gnu/usr.bin/clang/liblldbUtility/../../../llvm/lldb/source/Utility/SelectHelper.cpp" , 98); | ||||
| 99 | if (m_fd_map.size() > FD_SETSIZE1024) | ||||
| 100 | return lldb_private::Status("Too many file descriptors for select()"); | ||||
| 101 | #endif | ||||
| 102 | |||||
| 103 | std::optional<lldb::socket_t> max_read_fd; | ||||
| 104 | std::optional<lldb::socket_t> max_write_fd; | ||||
| 105 | std::optional<lldb::socket_t> max_error_fd; | ||||
| 106 | std::optional<lldb::socket_t> max_fd; | ||||
| 107 | for (auto &pair : m_fd_map) { | ||||
| 108 | pair.second.PrepareForSelect(); | ||||
| 109 | const lldb::socket_t fd = pair.first; | ||||
| 110 | #if !defined(__APPLE__) && !defined(_WIN32) | ||||
| 111 | lldbassert(fd < static_cast<int>(FD_SETSIZE))lldb_private::lldb_assert(static_cast<bool>(fd < static_cast <int>(1024)), "fd < static_cast<int>(FD_SETSIZE)" , __FUNCTION__, "/usr/src/gnu/usr.bin/clang/liblldbUtility/../../../llvm/lldb/source/Utility/SelectHelper.cpp" , 111); | ||||
| |||||
| 112 | if (fd
| ||||
| 113 | error.SetErrorStringWithFormat("%i is too large for select()", fd); | ||||
| 114 | return error; | ||||
| 115 | } | ||||
| 116 | #endif | ||||
| 117 | if (pair.second.read_set) | ||||
| 118 | updateMaxFd(max_read_fd, fd); | ||||
| 119 | if (pair.second.write_set) | ||||
| 120 | updateMaxFd(max_write_fd, fd); | ||||
| 121 | if (pair.second.error_set) | ||||
| 122 | updateMaxFd(max_error_fd, fd); | ||||
| 123 | updateMaxFd(max_fd, fd); | ||||
| 124 | } | ||||
| 125 | |||||
| 126 | if (!max_fd) { | ||||
| 127 | error.SetErrorString("no valid file descriptors"); | ||||
| 128 | return error; | ||||
| 129 | } | ||||
| 130 | |||||
| 131 | const unsigned nfds = static_cast<unsigned>(*max_fd) + 1; | ||||
| 132 | fd_set *read_fdset_ptr = nullptr; | ||||
| 133 | fd_set *write_fdset_ptr = nullptr; | ||||
| 134 | fd_set *error_fdset_ptr = nullptr; | ||||
| 135 | // Initialize and zero out the fdsets | ||||
| 136 | #if defined(__APPLE__) | ||||
| 137 | llvm::SmallVector<fd_set, 1> read_fdset; | ||||
| 138 | llvm::SmallVector<fd_set, 1> write_fdset; | ||||
| 139 | llvm::SmallVector<fd_set, 1> error_fdset; | ||||
| 140 | |||||
| 141 | if (max_read_fd.has_value()) { | ||||
| 142 | read_fdset.resize((nfds / FD_SETSIZE1024) + 1); | ||||
| 143 | read_fdset_ptr = read_fdset.data(); | ||||
| 144 | } | ||||
| 145 | if (max_write_fd.has_value()) { | ||||
| 146 | write_fdset.resize((nfds / FD_SETSIZE1024) + 1); | ||||
| 147 | write_fdset_ptr = write_fdset.data(); | ||||
| 148 | } | ||||
| 149 | if (max_error_fd.has_value()) { | ||||
| 150 | error_fdset.resize((nfds / FD_SETSIZE1024) + 1); | ||||
| 151 | error_fdset_ptr = error_fdset.data(); | ||||
| 152 | } | ||||
| 153 | for (auto &fd_set : read_fdset) | ||||
| 154 | FD_ZERO(&fd_set)do { fd_set *_p = (&fd_set); __size_t _n = (((1024) + ((( (unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(sizeof (__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[--_n] = 0; } while (0); | ||||
| 155 | for (auto &fd_set : write_fdset) | ||||
| 156 | FD_ZERO(&fd_set)do { fd_set *_p = (&fd_set); __size_t _n = (((1024) + ((( (unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(sizeof (__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[--_n] = 0; } while (0); | ||||
| 157 | for (auto &fd_set : error_fdset) | ||||
| 158 | FD_ZERO(&fd_set)do { fd_set *_p = (&fd_set); __size_t _n = (((1024) + ((( (unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(sizeof (__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[--_n] = 0; } while (0); | ||||
| 159 | #else | ||||
| 160 | fd_set read_fdset; | ||||
| 161 | fd_set write_fdset; | ||||
| 162 | fd_set error_fdset; | ||||
| 163 | |||||
| 164 | if (max_read_fd) { | ||||
| 165 | FD_ZERO(&read_fdset)do { fd_set *_p = (&read_fdset); __size_t _n = (((1024) + ((((unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)( sizeof(__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[ --_n] = 0; } while (0); | ||||
| 166 | read_fdset_ptr = &read_fdset; | ||||
| 167 | } | ||||
| 168 | if (max_write_fd) { | ||||
| 169 | FD_ZERO(&write_fdset)do { fd_set *_p = (&write_fdset); __size_t _n = (((1024) + ((((unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)( sizeof(__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[ --_n] = 0; } while (0); | ||||
| 170 | write_fdset_ptr = &write_fdset; | ||||
| 171 | } | ||||
| 172 | if (max_error_fd) { | ||||
| 173 | FD_ZERO(&error_fdset)do { fd_set *_p = (&error_fdset); __size_t _n = (((1024) + ((((unsigned)(sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)( sizeof(__fd_mask) * 8)))); while (_n > 0) _p->fds_bits[ --_n] = 0; } while (0); | ||||
| 174 | error_fdset_ptr = &error_fdset; | ||||
| 175 | } | ||||
| 176 | #endif | ||||
| 177 | // Set the FD bits in the fdsets for read/write/error | ||||
| 178 | for (auto &pair : m_fd_map) { | ||||
| 179 | const lldb::socket_t fd = pair.first; | ||||
| 180 | |||||
| 181 | if (pair.second.read_set) | ||||
| 182 | FD_SET(fd, read_fdset_ptr)__fd_set((fd), (read_fdset_ptr)); | ||||
| 183 | |||||
| 184 | if (pair.second.write_set) | ||||
| 185 | FD_SET(fd, write_fdset_ptr)__fd_set((fd), (write_fdset_ptr)); | ||||
| 186 | |||||
| 187 | if (pair.second.error_set) | ||||
| 188 | FD_SET(fd, error_fdset_ptr)__fd_set((fd), (error_fdset_ptr)); | ||||
| 189 | } | ||||
| 190 | |||||
| 191 | // Setup our timeout time value if needed | ||||
| 192 | struct timeval *tv_ptr = nullptr; | ||||
| 193 | struct timeval tv = {0, 0}; | ||||
| 194 | |||||
| 195 | while (true) { | ||||
| 196 | using namespace std::chrono; | ||||
| 197 | // Setup out relative timeout based on the end time if we have one | ||||
| 198 | if (m_end_time) { | ||||
| 199 | tv_ptr = &tv; | ||||
| 200 | const auto remaining_dur = | ||||
| 201 | duration_cast<microseconds>(*m_end_time - steady_clock::now()); | ||||
| 202 | if (remaining_dur.count() > 0) { | ||||
| 203 | // Wait for a specific amount of time | ||||
| 204 | const auto dur_secs = duration_cast<seconds>(remaining_dur); | ||||
| 205 | const auto dur_usecs = remaining_dur % seconds(1); | ||||
| 206 | tv.tv_sec = dur_secs.count(); | ||||
| 207 | tv.tv_usec = dur_usecs.count(); | ||||
| 208 | } else { | ||||
| 209 | // Just poll once with no timeout | ||||
| 210 | tv.tv_sec = 0; | ||||
| 211 | tv.tv_usec = 0; | ||||
| 212 | } | ||||
| 213 | } | ||||
| 214 | const int num_set_fds = ::select(nfds, read_fdset_ptr, write_fdset_ptr, | ||||
| 215 | error_fdset_ptr, tv_ptr); | ||||
| 216 | if (num_set_fds < 0) { | ||||
| 217 | // We got an error | ||||
| 218 | error.SetErrorToErrno(); | ||||
| 219 | if (error.GetError() == EINTR4) { | ||||
| 220 | error.Clear(); | ||||
| 221 | continue; // Keep calling select if we get EINTR | ||||
| 222 | } else | ||||
| 223 | return error; | ||||
| 224 | } else if (num_set_fds == 0) { | ||||
| 225 | // Timeout | ||||
| 226 | error.SetError(ETIMEDOUT60, lldb::eErrorTypePOSIX); | ||||
| 227 | error.SetErrorString("timed out"); | ||||
| 228 | return error; | ||||
| 229 | } else { | ||||
| 230 | // One or more descriptors were set, update the FDInfo::select_is_set | ||||
| 231 | // mask so users can ask the SelectHelper class so clients can call one | ||||
| 232 | // of: | ||||
| 233 | |||||
| 234 | for (auto &pair : m_fd_map) { | ||||
| 235 | const int fd = pair.first; | ||||
| 236 | |||||
| 237 | if (pair.second.read_set) { | ||||
| 238 | if (FD_ISSET(fd, read_fdset_ptr)__fd_isset((fd), (read_fdset_ptr))) | ||||
| 239 | pair.second.read_is_set = true; | ||||
| 240 | } | ||||
| 241 | if (pair.second.write_set) { | ||||
| 242 | if (FD_ISSET(fd, write_fdset_ptr)__fd_isset((fd), (write_fdset_ptr))) | ||||
| 243 | pair.second.write_is_set = true; | ||||
| 244 | } | ||||
| 245 | if (pair.second.error_set) { | ||||
| 246 | if (FD_ISSET(fd, error_fdset_ptr)__fd_isset((fd), (error_fdset_ptr))) | ||||
| 247 | pair.second.error_is_set = true; | ||||
| 248 | } | ||||
| 249 | } | ||||
| 250 | break; | ||||
| 251 | } | ||||
| 252 | } | ||||
| 253 | return error; | ||||
| 254 | } |
| 1 | /* $OpenBSD: select.h,v 1.17 2016/09/12 19:41:20 guenther Exp $ */ | |||
| 2 | ||||
| 3 | /*- | |||
| 4 | * Copyright (c) 1992, 1993 | |||
| 5 | * The Regents of the University of California. All rights reserved. | |||
| 6 | * | |||
| 7 | * Redistribution and use in source and binary forms, with or without | |||
| 8 | * modification, are permitted provided that the following conditions | |||
| 9 | * are met: | |||
| 10 | * 1. Redistributions of source code must retain the above copyright | |||
| 11 | * notice, this list of conditions and the following disclaimer. | |||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | |||
| 13 | * notice, this list of conditions and the following disclaimer in the | |||
| 14 | * documentation and/or other materials provided with the distribution. | |||
| 15 | * 3. Neither the name of the University nor the names of its contributors | |||
| 16 | * may be used to endorse or promote products derived from this software | |||
| 17 | * without specific prior written permission. | |||
| 18 | * | |||
| 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||
| 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
| 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
| 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||
| 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
| 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
| 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
| 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
| 29 | * SUCH DAMAGE. | |||
| 30 | * | |||
| 31 | * @(#)select.h 8.2 (Berkeley) 1/4/94 | |||
| 32 | */ | |||
| 33 | ||||
| 34 | #ifndef _SYS_SELECT_H_ | |||
| 35 | #define _SYS_SELECT_H_ | |||
| 36 | ||||
| 37 | #include <sys/types.h> | |||
| 38 | ||||
| 39 | #ifndef _TIMEVAL_DECLARED | |||
| 40 | #define _TIMEVAL_DECLARED | |||
| 41 | struct timeval { | |||
| 42 | time_t tv_sec; /* seconds */ | |||
| 43 | suseconds_t tv_usec; /* and microseconds */ | |||
| 44 | }; | |||
| 45 | #endif | |||
| 46 | ||||
| 47 | #ifndef _TIMESPEC_DECLARED | |||
| 48 | #define _TIMESPEC_DECLARED | |||
| 49 | struct timespec { | |||
| 50 | time_t tv_sec; /* seconds */ | |||
| 51 | long tv_nsec; /* and nanoseconds */ | |||
| 52 | }; | |||
| 53 | #endif | |||
| 54 | ||||
| 55 | /* | |||
| 56 | * Select uses bit masks of file descriptors in longs. These macros | |||
| 57 | * manipulate such bit fields (the filesystem macros use chars). | |||
| 58 | * FD_SETSIZE may be defined by the user, but the default here should | |||
| 59 | * be enough for most uses. | |||
| 60 | */ | |||
| 61 | #ifndef FD_SETSIZE1024 | |||
| 62 | #define FD_SETSIZE1024 1024 | |||
| 63 | #endif | |||
| 64 | ||||
| 65 | /* | |||
| 66 | * We don't want to pollute the namespace with select(2) internals. | |||
| 67 | * Non-underscore versions are exposed later #if __BSD_VISIBLE | |||
| 68 | */ | |||
| 69 | #define __NBBY8 8 /* number of bits in a byte */ | |||
| 70 | typedef uint32_t __fd_mask; | |||
| 71 | #define __NFDBITS((unsigned)(sizeof(__fd_mask) * 8)) ((unsigned)(sizeof(__fd_mask) * __NBBY8)) /* bits per mask */ | |||
| 72 | #define __howmany(x, y)(((x) + ((y) - 1)) / (y)) (((x) + ((y) - 1)) / (y)) | |||
| 73 | ||||
| 74 | typedef struct fd_set { | |||
| 75 | __fd_mask fds_bits[__howmany(FD_SETSIZE, __NFDBITS)(((1024) + ((((unsigned)(sizeof(__fd_mask) * 8))) - 1)) / ((( unsigned)(sizeof(__fd_mask) * 8))))]; | |||
| 76 | } fd_set; | |||
| 77 | ||||
| 78 | static __inlineinline void | |||
| 79 | __fd_set(int fd, fd_set *p) | |||
| 80 | { | |||
| 81 | p->fds_bits[fd / __NFDBITS((unsigned)(sizeof(__fd_mask) * 8))] |= (1U << (fd % __NFDBITS((unsigned)(sizeof(__fd_mask) * 8)))); | |||
| 82 | } | |||
| 83 | #define FD_SET(n, p)__fd_set((n), (p)) __fd_set((n), (p)) | |||
| 84 | ||||
| 85 | static __inlineinline void | |||
| 86 | __fd_clr(int fd, fd_set *p) | |||
| 87 | { | |||
| 88 | p->fds_bits[fd / __NFDBITS((unsigned)(sizeof(__fd_mask) * 8))] &= ~(1U << (fd % __NFDBITS((unsigned)(sizeof(__fd_mask) * 8)))); | |||
| 89 | } | |||
| 90 | #define FD_CLR(n, p)__fd_clr((n), (p)) __fd_clr((n), (p)) | |||
| 91 | ||||
| 92 | static __inlineinline int | |||
| 93 | __fd_isset(int fd, const fd_set *p) | |||
| 94 | { | |||
| 95 | return (p->fds_bits[fd / __NFDBITS((unsigned)(sizeof(__fd_mask) * 8))] & (1U << (fd % __NFDBITS((unsigned)(sizeof(__fd_mask) * 8))))); | |||
| ||||
| 96 | } | |||
| 97 | #define FD_ISSET(n, p)__fd_isset((n), (p)) __fd_isset((n), (p)) | |||
| 98 | ||||
| 99 | #if __BSD_VISIBLE1 | |||
| 100 | #define FD_COPY(f, t)(void)(*(t) = *(f)) (void)(*(t) = *(f)) | |||
| 101 | #endif | |||
| 102 | #define FD_ZERO(p)do { fd_set *_p = (p); __size_t _n = (((1024) + ((((unsigned) (sizeof(__fd_mask) * 8))) - 1)) / (((unsigned)(sizeof(__fd_mask ) * 8)))); while (_n > 0) _p->fds_bits[--_n] = 0; } while (0) do { \ | |||
| 103 | fd_set *_p = (p); \ | |||
| 104 | __size_t _n = __howmany(FD_SETSIZE, __NFDBITS)(((1024) + ((((unsigned)(sizeof(__fd_mask) * 8))) - 1)) / ((( unsigned)(sizeof(__fd_mask) * 8)))); \ | |||
| 105 | \ | |||
| 106 | while (_n > 0) \ | |||
| 107 | _p->fds_bits[--_n] = 0; \ | |||
| 108 | } while (0) | |||
| 109 | ||||
| 110 | #if __BSD_VISIBLE1 | |||
| 111 | #define NBBY8 __NBBY8 | |||
| 112 | #define fd_mask__fd_mask __fd_mask | |||
| 113 | #define NFDBITS((unsigned)(sizeof(__fd_mask) * 8)) __NFDBITS((unsigned)(sizeof(__fd_mask) * 8)) | |||
| 114 | #ifndef howmany | |||
| 115 | #define howmany(x, y)(((x) + ((y) - 1)) / (y)) __howmany(x, y)(((x) + ((y) - 1)) / (y)) | |||
| 116 | #endif | |||
| 117 | #endif /* __BSD_VISIBLE */ | |||
| 118 | ||||
| 119 | #ifndef _KERNEL | |||
| 120 | #ifndef _SIGSET_T_DEFINED_ | |||
| 121 | #define _SIGSET_T_DEFINED_ | |||
| 122 | typedef unsigned int sigset_t; | |||
| 123 | #endif | |||
| 124 | ||||
| 125 | #ifndef _SELECT_DEFINED_ | |||
| 126 | #define _SELECT_DEFINED_ | |||
| 127 | __BEGIN_DECLSextern "C" { | |||
| 128 | int select(int, fd_set * __restrict, fd_set * __restrict, | |||
| 129 | fd_set * __restrict, struct timeval * __restrict); | |||
| 130 | int pselect(int, fd_set * __restrict, fd_set * __restrict, | |||
| 131 | fd_set * __restrict, const struct timespec * __restrict, | |||
| 132 | const sigset_t * __restrict); | |||
| 133 | __END_DECLS} | |||
| 134 | #endif | |||
| 135 | #endif /* !_KERNEL */ | |||
| 136 | ||||
| 137 | #endif /* !_SYS_SELECT_H_ */ |