Newer
Older
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
Yang Tse
committed
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include "setup.h"
#ifndef WIN32
#ifdef HAVE_SYS_TIME_H
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> /* <netinet/tcp.h> may need it */
#endif
Daniel Stenberg
committed
#ifdef HAVE_SYS_UN_H
#include <sys/un.h> /* for sockaddr_un */
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h> /* for TCP_NODELAY */
#ifdef HAVE_SYS_IOCTL_H
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_NETINET_IN_H
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <stdlib.h> /* required for free() prototype, without it, this crashes */
#endif /* on macos 68K */
#if (defined(HAVE_FIONBIO) && defined(NETWARE))
#undef in_addr_t
#define in_addr_t unsigned long
#endif
#endif /* !WIN32 */
#include <stdio.h>
#include <errno.h>
#include "urldata.h"
#include "sendf.h"
#include "connect.h"
#include "memory.h"
#include "url.h" /* for Curl_safefree() */
Daniel Stenberg
committed
#include "multiif.h"
Daniel Stenberg
committed
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
#include "inet_ntop.h"
Daniel Stenberg
committed
#include "sslgen.h" /* for Curl_ssl_check_cxn() */
/* The last #include file should be: */
#include "memdebug.h"
#ifdef __SYMBIAN32__
/* This isn't actually supported under Symbian OS */
#undef SO_NOSIGPIPE
#endif
static bool verifyconnect(curl_socket_t sockfd, int *error);
Daniel Stenberg
committed
Daniel Stenberg
committed
static curl_socket_t
singleipconnect(struct connectdata *conn,
const Curl_addrinfo *ai, /* start connecting to this */
Daniel Stenberg
committed
long timeout_ms,
bool *connected);
Daniel Stenberg
committed
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*
* Curl_timeleft() returns the amount of milliseconds left allowed for the
* transfer/connection. If the value is negative, the timeout time has already
* elapsed.
*
* If 'nowp' is non-NULL, it points to the current time.
* 'duringconnect' is FALSE if not during a connect, as then of course the
* connect timeout is not taken into account!
*/
long Curl_timeleft(struct connectdata *conn,
struct timeval *nowp,
bool duringconnect)
{
struct SessionHandle *data = conn->data;
int timeout_set = 0;
long timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0;
struct timeval now;
/* if a timeout is set, use the most restrictive one */
if(data->set.timeout > 0)
timeout_set |= 1;
if(duringconnect && (data->set.connecttimeout > 0))
timeout_set |= 2;
switch (timeout_set) {
case 1:
timeout_ms = data->set.timeout;
break;
case 2:
timeout_ms = data->set.connecttimeout;
break;
case 3:
if(data->set.timeout < data->set.connecttimeout)
timeout_ms = data->set.timeout;
else
timeout_ms = data->set.connecttimeout;
break;
default:
/* use the default */
if(!duringconnect)
/* if we're not during connect, there's no default timeout so if we're
at zero we better just return zero and not make it a negative number
by the math below */
return 0;
break;
}
if(!nowp) {
now = Curl_tvnow();
nowp = &now;
}
/* substract elapsed time */
timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startsingle);
return timeout_ms;
}
/*
* Curl_nonblock() set the given socket to either blocking or non-blocking
* mode based on the 'nonblock' boolean argument. This function is highly
* portable.
int Curl_nonblock(curl_socket_t sockfd, /* operate on this */
Daniel Stenberg
committed
int nonblock /* TRUE or FALSE */)
#define SETBLOCK 0
/* most recent unix versions */
Daniel Stenberg
committed
if(FALSE != nonblock)
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
/* older unix versions */
Loading full blame...