xref: /aosp_15_r20/external/cronet/third_party/libevent/evutil.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker /*
2*6777b538SAndroid Build Coastguard Worker  * Copyright (c) 2007 Niels Provos <[email protected]>
3*6777b538SAndroid Build Coastguard Worker  * All rights reserved.
4*6777b538SAndroid Build Coastguard Worker  *
5*6777b538SAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
6*6777b538SAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
7*6777b538SAndroid Build Coastguard Worker  * are met:
8*6777b538SAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
9*6777b538SAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
10*6777b538SAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
11*6777b538SAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
12*6777b538SAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
13*6777b538SAndroid Build Coastguard Worker  * 3. The name of the author may not be used to endorse or promote products
14*6777b538SAndroid Build Coastguard Worker  *    derived from this software without specific prior written permission.
15*6777b538SAndroid Build Coastguard Worker  *
16*6777b538SAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17*6777b538SAndroid Build Coastguard Worker  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18*6777b538SAndroid Build Coastguard Worker  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19*6777b538SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20*6777b538SAndroid Build Coastguard Worker  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21*6777b538SAndroid Build Coastguard Worker  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22*6777b538SAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23*6777b538SAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*6777b538SAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25*6777b538SAndroid Build Coastguard Worker  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*6777b538SAndroid Build Coastguard Worker  */
27*6777b538SAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
28*6777b538SAndroid Build Coastguard Worker #include "config.h"
29*6777b538SAndroid Build Coastguard Worker #endif
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker #ifdef WIN32
32*6777b538SAndroid Build Coastguard Worker #include <winsock2.h>
33*6777b538SAndroid Build Coastguard Worker #define WIN32_LEAN_AND_MEAN
34*6777b538SAndroid Build Coastguard Worker #include <windows.h>
35*6777b538SAndroid Build Coastguard Worker #undef WIN32_LEAN_AND_MEAN
36*6777b538SAndroid Build Coastguard Worker #endif
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker #include <sys/types.h>
39*6777b538SAndroid Build Coastguard Worker #ifdef HAVE_SYS_SOCKET_H
40*6777b538SAndroid Build Coastguard Worker #include <sys/socket.h>
41*6777b538SAndroid Build Coastguard Worker #endif
42*6777b538SAndroid Build Coastguard Worker #ifdef HAVE_UNISTD_H
43*6777b538SAndroid Build Coastguard Worker #include <unistd.h>
44*6777b538SAndroid Build Coastguard Worker #endif
45*6777b538SAndroid Build Coastguard Worker #ifdef HAVE_FCNTL_H
46*6777b538SAndroid Build Coastguard Worker #include <fcntl.h>
47*6777b538SAndroid Build Coastguard Worker #endif
48*6777b538SAndroid Build Coastguard Worker #ifdef HAVE_STDLIB_H
49*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
50*6777b538SAndroid Build Coastguard Worker #endif
51*6777b538SAndroid Build Coastguard Worker #include <errno.h>
52*6777b538SAndroid Build Coastguard Worker #if defined WIN32 && !defined(HAVE_GETTIMEOFDAY_H)
53*6777b538SAndroid Build Coastguard Worker #include <sys/timeb.h>
54*6777b538SAndroid Build Coastguard Worker #endif
55*6777b538SAndroid Build Coastguard Worker #include <stdio.h>
56*6777b538SAndroid Build Coastguard Worker #include <signal.h>
57*6777b538SAndroid Build Coastguard Worker 
58*6777b538SAndroid Build Coastguard Worker #include <sys/queue.h>
59*6777b538SAndroid Build Coastguard Worker #include "event.h"
60*6777b538SAndroid Build Coastguard Worker #include "event-internal.h"
61*6777b538SAndroid Build Coastguard Worker #include "evutil.h"
62*6777b538SAndroid Build Coastguard Worker #include "log.h"
63*6777b538SAndroid Build Coastguard Worker 
64*6777b538SAndroid Build Coastguard Worker int
evutil_socketpair(int family,int type,int protocol,int fd[2])65*6777b538SAndroid Build Coastguard Worker evutil_socketpair(int family, int type, int protocol, int fd[2])
66*6777b538SAndroid Build Coastguard Worker {
67*6777b538SAndroid Build Coastguard Worker #ifndef WIN32
68*6777b538SAndroid Build Coastguard Worker 	return socketpair(family, type, protocol, fd);
69*6777b538SAndroid Build Coastguard Worker #else
70*6777b538SAndroid Build Coastguard Worker 	/* This code is originally from Tor.  Used with permission. */
71*6777b538SAndroid Build Coastguard Worker 
72*6777b538SAndroid Build Coastguard Worker 	/* This socketpair does not work when localhost is down. So
73*6777b538SAndroid Build Coastguard Worker 	 * it's really not the same thing at all. But it's close enough
74*6777b538SAndroid Build Coastguard Worker 	 * for now, and really, when localhost is down sometimes, we
75*6777b538SAndroid Build Coastguard Worker 	 * have other problems too.
76*6777b538SAndroid Build Coastguard Worker 	 */
77*6777b538SAndroid Build Coastguard Worker 	int listener = -1;
78*6777b538SAndroid Build Coastguard Worker 	int connector = -1;
79*6777b538SAndroid Build Coastguard Worker 	int acceptor = -1;
80*6777b538SAndroid Build Coastguard Worker 	struct sockaddr_in listen_addr;
81*6777b538SAndroid Build Coastguard Worker 	struct sockaddr_in connect_addr;
82*6777b538SAndroid Build Coastguard Worker 	int size;
83*6777b538SAndroid Build Coastguard Worker 	int saved_errno = -1;
84*6777b538SAndroid Build Coastguard Worker 
85*6777b538SAndroid Build Coastguard Worker 	if (protocol
86*6777b538SAndroid Build Coastguard Worker #ifdef AF_UNIX
87*6777b538SAndroid Build Coastguard Worker 		|| family != AF_UNIX
88*6777b538SAndroid Build Coastguard Worker #endif
89*6777b538SAndroid Build Coastguard Worker 		) {
90*6777b538SAndroid Build Coastguard Worker 		EVUTIL_SET_SOCKET_ERROR(WSAEAFNOSUPPORT);
91*6777b538SAndroid Build Coastguard Worker 		return -1;
92*6777b538SAndroid Build Coastguard Worker 	}
93*6777b538SAndroid Build Coastguard Worker 	if (!fd) {
94*6777b538SAndroid Build Coastguard Worker 		EVUTIL_SET_SOCKET_ERROR(WSAEINVAL);
95*6777b538SAndroid Build Coastguard Worker 		return -1;
96*6777b538SAndroid Build Coastguard Worker 	}
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker 	listener = socket(AF_INET, type, 0);
99*6777b538SAndroid Build Coastguard Worker 	if (listener < 0)
100*6777b538SAndroid Build Coastguard Worker 		return -1;
101*6777b538SAndroid Build Coastguard Worker 	memset(&listen_addr, 0, sizeof(listen_addr));
102*6777b538SAndroid Build Coastguard Worker 	listen_addr.sin_family = AF_INET;
103*6777b538SAndroid Build Coastguard Worker 	listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
104*6777b538SAndroid Build Coastguard Worker 	listen_addr.sin_port = 0;	/* kernel chooses port.	 */
105*6777b538SAndroid Build Coastguard Worker 	if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
106*6777b538SAndroid Build Coastguard Worker 		== -1)
107*6777b538SAndroid Build Coastguard Worker 		goto tidy_up_and_fail;
108*6777b538SAndroid Build Coastguard Worker 	if (listen(listener, 1) == -1)
109*6777b538SAndroid Build Coastguard Worker 		goto tidy_up_and_fail;
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker 	connector = socket(AF_INET, type, 0);
112*6777b538SAndroid Build Coastguard Worker 	if (connector < 0)
113*6777b538SAndroid Build Coastguard Worker 		goto tidy_up_and_fail;
114*6777b538SAndroid Build Coastguard Worker 	/* We want to find out the port number to connect to.  */
115*6777b538SAndroid Build Coastguard Worker 	size = sizeof(connect_addr);
116*6777b538SAndroid Build Coastguard Worker 	if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
117*6777b538SAndroid Build Coastguard Worker 		goto tidy_up_and_fail;
118*6777b538SAndroid Build Coastguard Worker 	if (size != sizeof (connect_addr))
119*6777b538SAndroid Build Coastguard Worker 		goto abort_tidy_up_and_fail;
120*6777b538SAndroid Build Coastguard Worker 	if (connect(connector, (struct sockaddr *) &connect_addr,
121*6777b538SAndroid Build Coastguard Worker 				sizeof(connect_addr)) == -1)
122*6777b538SAndroid Build Coastguard Worker 		goto tidy_up_and_fail;
123*6777b538SAndroid Build Coastguard Worker 
124*6777b538SAndroid Build Coastguard Worker 	size = sizeof(listen_addr);
125*6777b538SAndroid Build Coastguard Worker 	acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
126*6777b538SAndroid Build Coastguard Worker 	if (acceptor < 0)
127*6777b538SAndroid Build Coastguard Worker 		goto tidy_up_and_fail;
128*6777b538SAndroid Build Coastguard Worker 	if (size != sizeof(listen_addr))
129*6777b538SAndroid Build Coastguard Worker 		goto abort_tidy_up_and_fail;
130*6777b538SAndroid Build Coastguard Worker 	EVUTIL_CLOSESOCKET(listener);
131*6777b538SAndroid Build Coastguard Worker 	/* Now check we are talking to ourself by matching port and host on the
132*6777b538SAndroid Build Coastguard Worker 	   two sockets.	 */
133*6777b538SAndroid Build Coastguard Worker 	if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
134*6777b538SAndroid Build Coastguard Worker 		goto tidy_up_and_fail;
135*6777b538SAndroid Build Coastguard Worker 	if (size != sizeof (connect_addr)
136*6777b538SAndroid Build Coastguard Worker 		|| listen_addr.sin_family != connect_addr.sin_family
137*6777b538SAndroid Build Coastguard Worker 		|| listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
138*6777b538SAndroid Build Coastguard Worker 		|| listen_addr.sin_port != connect_addr.sin_port)
139*6777b538SAndroid Build Coastguard Worker 		goto abort_tidy_up_and_fail;
140*6777b538SAndroid Build Coastguard Worker 	fd[0] = connector;
141*6777b538SAndroid Build Coastguard Worker 	fd[1] = acceptor;
142*6777b538SAndroid Build Coastguard Worker 
143*6777b538SAndroid Build Coastguard Worker 	return 0;
144*6777b538SAndroid Build Coastguard Worker 
145*6777b538SAndroid Build Coastguard Worker  abort_tidy_up_and_fail:
146*6777b538SAndroid Build Coastguard Worker 	saved_errno = WSAECONNABORTED;
147*6777b538SAndroid Build Coastguard Worker  tidy_up_and_fail:
148*6777b538SAndroid Build Coastguard Worker 	if (saved_errno < 0)
149*6777b538SAndroid Build Coastguard Worker 		saved_errno = WSAGetLastError();
150*6777b538SAndroid Build Coastguard Worker 	if (listener != -1)
151*6777b538SAndroid Build Coastguard Worker 		EVUTIL_CLOSESOCKET(listener);
152*6777b538SAndroid Build Coastguard Worker 	if (connector != -1)
153*6777b538SAndroid Build Coastguard Worker 		EVUTIL_CLOSESOCKET(connector);
154*6777b538SAndroid Build Coastguard Worker 	if (acceptor != -1)
155*6777b538SAndroid Build Coastguard Worker 		EVUTIL_CLOSESOCKET(acceptor);
156*6777b538SAndroid Build Coastguard Worker 
157*6777b538SAndroid Build Coastguard Worker 	EVUTIL_SET_SOCKET_ERROR(saved_errno);
158*6777b538SAndroid Build Coastguard Worker 	return -1;
159*6777b538SAndroid Build Coastguard Worker #endif
160*6777b538SAndroid Build Coastguard Worker }
161*6777b538SAndroid Build Coastguard Worker 
162*6777b538SAndroid Build Coastguard Worker int
evutil_make_socket_nonblocking(int fd)163*6777b538SAndroid Build Coastguard Worker evutil_make_socket_nonblocking(int fd)
164*6777b538SAndroid Build Coastguard Worker {
165*6777b538SAndroid Build Coastguard Worker #ifdef WIN32
166*6777b538SAndroid Build Coastguard Worker 	{
167*6777b538SAndroid Build Coastguard Worker 		unsigned long nonblocking = 1;
168*6777b538SAndroid Build Coastguard Worker 		ioctlsocket(fd, FIONBIO, (unsigned long*) &nonblocking);
169*6777b538SAndroid Build Coastguard Worker 	}
170*6777b538SAndroid Build Coastguard Worker #else
171*6777b538SAndroid Build Coastguard Worker 	{
172*6777b538SAndroid Build Coastguard Worker 		int flags;
173*6777b538SAndroid Build Coastguard Worker 		if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
174*6777b538SAndroid Build Coastguard Worker 			event_warn("fcntl(%d, F_GETFL)", fd);
175*6777b538SAndroid Build Coastguard Worker 			return -1;
176*6777b538SAndroid Build Coastguard Worker 		}
177*6777b538SAndroid Build Coastguard Worker 		if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
178*6777b538SAndroid Build Coastguard Worker 			event_warn("fcntl(%d, F_SETFL)", fd);
179*6777b538SAndroid Build Coastguard Worker 			return -1;
180*6777b538SAndroid Build Coastguard Worker 		}
181*6777b538SAndroid Build Coastguard Worker 	}
182*6777b538SAndroid Build Coastguard Worker #endif
183*6777b538SAndroid Build Coastguard Worker 	return 0;
184*6777b538SAndroid Build Coastguard Worker }
185*6777b538SAndroid Build Coastguard Worker 
186*6777b538SAndroid Build Coastguard Worker ev_int64_t
evutil_strtoll(const char * s,char ** endptr,int base)187*6777b538SAndroid Build Coastguard Worker evutil_strtoll(const char *s, char **endptr, int base)
188*6777b538SAndroid Build Coastguard Worker {
189*6777b538SAndroid Build Coastguard Worker #ifdef HAVE_STRTOLL
190*6777b538SAndroid Build Coastguard Worker 	return (ev_int64_t)strtoll(s, endptr, base);
191*6777b538SAndroid Build Coastguard Worker #elif SIZEOF_LONG == 8
192*6777b538SAndroid Build Coastguard Worker 	return (ev_int64_t)strtol(s, endptr, base);
193*6777b538SAndroid Build Coastguard Worker #elif defined(WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
194*6777b538SAndroid Build Coastguard Worker 	/* XXXX on old versions of MS APIs, we only support base
195*6777b538SAndroid Build Coastguard Worker 	 * 10. */
196*6777b538SAndroid Build Coastguard Worker 	ev_int64_t r;
197*6777b538SAndroid Build Coastguard Worker 	if (base != 10)
198*6777b538SAndroid Build Coastguard Worker 		return 0;
199*6777b538SAndroid Build Coastguard Worker 	r = (ev_int64_t) _atoi64(s);
200*6777b538SAndroid Build Coastguard Worker 	while (isspace(*s))
201*6777b538SAndroid Build Coastguard Worker 		++s;
202*6777b538SAndroid Build Coastguard Worker 	while (isdigit(*s))
203*6777b538SAndroid Build Coastguard Worker 		++s;
204*6777b538SAndroid Build Coastguard Worker 	if (endptr)
205*6777b538SAndroid Build Coastguard Worker 		*endptr = (char*) s;
206*6777b538SAndroid Build Coastguard Worker 	return r;
207*6777b538SAndroid Build Coastguard Worker #elif defined(WIN32)
208*6777b538SAndroid Build Coastguard Worker 	return (ev_int64_t) _strtoi64(s, endptr, base);
209*6777b538SAndroid Build Coastguard Worker #else
210*6777b538SAndroid Build Coastguard Worker #error "I don't know how to parse 64-bit integers."
211*6777b538SAndroid Build Coastguard Worker #endif
212*6777b538SAndroid Build Coastguard Worker }
213*6777b538SAndroid Build Coastguard Worker 
214*6777b538SAndroid Build Coastguard Worker #ifndef _EVENT_HAVE_GETTIMEOFDAY
215*6777b538SAndroid Build Coastguard Worker int
evutil_gettimeofday(struct timeval * tv,struct timezone * tz)216*6777b538SAndroid Build Coastguard Worker evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
217*6777b538SAndroid Build Coastguard Worker {
218*6777b538SAndroid Build Coastguard Worker 	struct _timeb tb;
219*6777b538SAndroid Build Coastguard Worker 
220*6777b538SAndroid Build Coastguard Worker 	if(tv == NULL)
221*6777b538SAndroid Build Coastguard Worker 		return -1;
222*6777b538SAndroid Build Coastguard Worker 
223*6777b538SAndroid Build Coastguard Worker 	_ftime(&tb);
224*6777b538SAndroid Build Coastguard Worker 	tv->tv_sec = (long) tb.time;
225*6777b538SAndroid Build Coastguard Worker 	tv->tv_usec = ((int) tb.millitm) * 1000;
226*6777b538SAndroid Build Coastguard Worker 	return 0;
227*6777b538SAndroid Build Coastguard Worker }
228*6777b538SAndroid Build Coastguard Worker #endif
229*6777b538SAndroid Build Coastguard Worker 
230*6777b538SAndroid Build Coastguard Worker int
evutil_snprintf(char * buf,size_t buflen,const char * format,...)231*6777b538SAndroid Build Coastguard Worker evutil_snprintf(char *buf, size_t buflen, const char *format, ...)
232*6777b538SAndroid Build Coastguard Worker {
233*6777b538SAndroid Build Coastguard Worker 	int r;
234*6777b538SAndroid Build Coastguard Worker 	va_list ap;
235*6777b538SAndroid Build Coastguard Worker 	va_start(ap, format);
236*6777b538SAndroid Build Coastguard Worker 	r = evutil_vsnprintf(buf, buflen, format, ap);
237*6777b538SAndroid Build Coastguard Worker 	va_end(ap);
238*6777b538SAndroid Build Coastguard Worker 	return r;
239*6777b538SAndroid Build Coastguard Worker }
240*6777b538SAndroid Build Coastguard Worker 
241*6777b538SAndroid Build Coastguard Worker int
evutil_vsnprintf(char * buf,size_t buflen,const char * format,va_list ap)242*6777b538SAndroid Build Coastguard Worker evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
243*6777b538SAndroid Build Coastguard Worker {
244*6777b538SAndroid Build Coastguard Worker #ifdef _MSC_VER
245*6777b538SAndroid Build Coastguard Worker 	int r = _vsnprintf(buf, buflen, format, ap);
246*6777b538SAndroid Build Coastguard Worker 	buf[buflen-1] = '\0';
247*6777b538SAndroid Build Coastguard Worker 	if (r >= 0)
248*6777b538SAndroid Build Coastguard Worker 		return r;
249*6777b538SAndroid Build Coastguard Worker 	else
250*6777b538SAndroid Build Coastguard Worker 		return _vscprintf(format, ap);
251*6777b538SAndroid Build Coastguard Worker #else
252*6777b538SAndroid Build Coastguard Worker 	int r = vsnprintf(buf, buflen, format, ap);
253*6777b538SAndroid Build Coastguard Worker 	buf[buflen-1] = '\0';
254*6777b538SAndroid Build Coastguard Worker 	return r;
255*6777b538SAndroid Build Coastguard Worker #endif
256*6777b538SAndroid Build Coastguard Worker }
257*6777b538SAndroid Build Coastguard Worker 
258*6777b538SAndroid Build Coastguard Worker static int
evutil_issetugid(void)259*6777b538SAndroid Build Coastguard Worker evutil_issetugid(void)
260*6777b538SAndroid Build Coastguard Worker {
261*6777b538SAndroid Build Coastguard Worker #ifdef _EVENT_HAVE_ISSETUGID
262*6777b538SAndroid Build Coastguard Worker 	return issetugid();
263*6777b538SAndroid Build Coastguard Worker #else
264*6777b538SAndroid Build Coastguard Worker 
265*6777b538SAndroid Build Coastguard Worker #ifdef _EVENT_HAVE_GETEUID
266*6777b538SAndroid Build Coastguard Worker 	if (getuid() != geteuid())
267*6777b538SAndroid Build Coastguard Worker 		return 1;
268*6777b538SAndroid Build Coastguard Worker #endif
269*6777b538SAndroid Build Coastguard Worker #ifdef _EVENT_HAVE_GETEGID
270*6777b538SAndroid Build Coastguard Worker 	if (getgid() != getegid())
271*6777b538SAndroid Build Coastguard Worker 		return 1;
272*6777b538SAndroid Build Coastguard Worker #endif
273*6777b538SAndroid Build Coastguard Worker 	return 0;
274*6777b538SAndroid Build Coastguard Worker #endif
275*6777b538SAndroid Build Coastguard Worker }
276*6777b538SAndroid Build Coastguard Worker 
277*6777b538SAndroid Build Coastguard Worker const char *
evutil_getenv(const char * varname)278*6777b538SAndroid Build Coastguard Worker evutil_getenv(const char *varname)
279*6777b538SAndroid Build Coastguard Worker {
280*6777b538SAndroid Build Coastguard Worker 	if (evutil_issetugid())
281*6777b538SAndroid Build Coastguard Worker 		return NULL;
282*6777b538SAndroid Build Coastguard Worker 
283*6777b538SAndroid Build Coastguard Worker 	return getenv(varname);
284*6777b538SAndroid Build Coastguard Worker }
285