1
/***************************************************************************
3
* Project ___| | | | _ \| |
5
* | (__| |_| | _ <| |___
6
* \___|\___/|_| \_\_____|
8
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
10
* This software is licensed as described in the file COPYING, which
11
* you should have received as part of this distribution. The terms
12
* are also available at http://curl.haxx.se/docs/copyright.html.
14
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
* copies of the Software, and permit persons to whom the Software is
16
* furnished to do so, under the terms of the COPYING file.
18
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
* KIND, either express or implied.
21
* $Id: select.c,v 1.5 2004/11/20 08:57:56 bagder Exp $
22
***************************************************************************/
26
#ifdef HAVE_SYS_SELECT_H
27
#include <sys/select.h>
29
#ifdef HAVE_SYS_TYPES_H
30
#include <sys/types.h>
33
#ifdef HAVE_SYS_TIME_H
38
#error "We can't compile without select() support!"
44
#define VALID_SOCK(s) (1) /* Win-sockets are not in range [0..FD_SETSIZE> */
46
#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
50
* This is an internal function used for waiting for read or write
51
* events on single file descriptors. It attempts to replace select()
52
* in order to avoid limits with FD_SETSIZE.
55
* -1 = system call error
57
* CSELECT_IN | CSELECT_OUT | CSELECT_ERR
59
int Curl_select(curl_socket_t readfd, curl_socket_t writefd, int timeout_ms)
68
if (readfd != CURL_SOCKET_BAD) {
70
pfd[num].events = POLLIN;
73
if (writefd != CURL_SOCKET_BAD) {
74
pfd[num].fd = writefd;
75
pfd[num].events = POLLOUT;
79
r = poll(pfd, num, timeout_ms);
88
if (readfd != CURL_SOCKET_BAD) {
89
if (pfd[num].revents & POLLIN)
91
if (pfd[num].revents & POLLERR)
95
if (writefd != CURL_SOCKET_BAD) {
96
if (pfd[num].revents & POLLOUT)
98
if (pfd[num].revents & POLLERR)
104
struct timeval timeout;
112
timeout.tv_sec = timeout_ms / 1000;
113
timeout.tv_usec = (timeout_ms % 1000) * 1000;
119
if (readfd != CURL_SOCKET_BAD) {
120
if (!VALID_SOCK(readfd)) {
124
FD_SET(readfd, &fds_read);
125
FD_SET(readfd, &fds_err);
130
if (writefd != CURL_SOCKET_BAD) {
131
if (!VALID_SOCK(writefd)) {
135
FD_SET(writefd, &fds_write);
136
FD_SET(writefd, &fds_err);
141
r = select(maxfd + 1, &fds_read, &fds_write, &fds_err, &timeout);
149
if (readfd != CURL_SOCKET_BAD) {
150
if (FD_ISSET(readfd, &fds_read))
152
if (FD_ISSET(readfd, &fds_err))
155
if (writefd != CURL_SOCKET_BAD) {
156
if (FD_ISSET(writefd, &fds_write))
158
if (FD_ISSET(writefd, &fds_err))
167
* This is a wrapper around poll(). If poll() does not exist, then
168
* select() is used instead. An error is returned if select() is
169
* being used and a file descriptor too large for FD_SETSIZE.
172
* -1 = system call error or fd >= FD_SETSIZE
174
* 1 = number of structures with non zero revent fields
176
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
178
#ifdef HAVE_POLL_FINE
179
return poll(ufds, nfds, timeout_ms);
181
struct timeval timeout;
182
struct timeval *ptimeout;
195
for (i = 0; i < nfds; i++) {
196
if (ufds[i].fd == CURL_SOCKET_BAD)
198
#ifndef WIN32 /* This is harmless and wrong on Win32 */
199
if (ufds[i].fd >= FD_SETSIZE) {
204
if (ufds[i].fd > maxfd)
206
if (ufds[i].events & POLLIN)
207
FD_SET(ufds[i].fd, &fds_read);
208
if (ufds[i].events & POLLOUT)
209
FD_SET(ufds[i].fd, &fds_write);
210
if (ufds[i].events & POLLERR)
211
FD_SET(ufds[i].fd, &fds_err);
214
if (timeout_ms < 0) {
215
ptimeout = NULL; /* wait forever */
217
timeout.tv_sec = timeout_ms / 1000;
218
timeout.tv_usec = (timeout_ms % 1000) * 1000;
222
r = select(maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
230
for (i = 0; i < nfds; i++) {
232
if (ufds[i].fd == CURL_SOCKET_BAD)
234
if (FD_ISSET(ufds[i].fd, &fds_read))
235
ufds[i].revents |= POLLIN;
236
if (FD_ISSET(ufds[i].fd, &fds_write))
237
ufds[i].revents |= POLLOUT;
238
if (FD_ISSET(ufds[i].fd, &fds_err))
239
ufds[i].revents |= POLLERR;
240
if (ufds[i].revents != 0)