Stop trying to #include the world in util.c
[tor.git] / src / common / util.c
blobc313fb5db86eb4bf6f96becce202442e754ddbe7
1 /* Copyright 2003 Roger Dingledine */
2 /* See LICENSE for licensing information */
3 /* $Id$ */
5 #include "../or/or.h"
6 #include "util.h"
7 #include "log.h"
9 void *tor_malloc(size_t size) {
10 void *result;
12 result = malloc(size);
14 if(!result) {
15 log_fn(LOG_ERR, "Out of memory. Dying.");
16 exit(1);
19 return result;
22 void
23 my_gettimeofday(struct timeval *timeval)
25 #ifdef HAVE_GETTIMEOFDAY
26 if (gettimeofday(timeval, NULL)) {
27 log_fn(LOG_ERR, "gettimeofday failed.");
28 /* If gettimeofday dies, we have either given a bad timezone (we didn't),
29 or segfaulted.*/
30 exit(1);
32 #elif defined(HAVE_FTIME)
33 ftime(timeval);
34 #else
35 #error "No way to get time."
36 #endif
37 return;
40 long
41 tv_udiff(struct timeval *start, struct timeval *end)
43 long udiff;
44 long end_usec = end->tv_usec;
45 long secdiff = end->tv_sec - start->tv_sec;
47 if (secdiff+1 > LONG_MAX/1000000) {
48 log_fn(LOG_NOTICE, "comparing times too far apart.");
49 return LONG_MAX;
52 udiff = secdiff*1000000L + (end_usec - start->tv_usec);
53 if(udiff < 0) {
54 log_fn(LOG_NOTICE, "start is after end. Returning 0.");
55 return 0;
57 return udiff;
60 int tv_cmp(struct timeval *a, struct timeval *b) {
61 if (a->tv_sec > b->tv_sec)
62 return 1;
63 if (a->tv_sec < b->tv_sec)
64 return -1;
65 if (a->tv_usec > b->tv_usec)
66 return 1;
67 if (a->tv_usec < b->tv_usec)
68 return -1;
69 return 0;
72 void tv_add(struct timeval *a, struct timeval *b) {
73 a->tv_usec += b->tv_usec;
74 a->tv_sec += b->tv_sec + (a->tv_usec / 1000000);
75 a->tv_usec %= 1000000;
78 void tv_addms(struct timeval *a, long ms) {
79 a->tv_usec += (ms * 1000) % 1000000;
80 a->tv_sec += ((ms * 1000) / 1000000) + (a->tv_usec / 1000000);
81 a->tv_usec %= 1000000;
84 void set_socket_nonblocking(int socket)
86 #ifdef _MSC_VER
87 /* Yes means no and no means yes. Do you not want to be nonblocking? */
88 int nonblocking = 0;
89 ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking);
90 #else
91 fcntl(socket, F_SETFL, O_NONBLOCK);
92 #endif
95 int spawn_func(int (*func)(void *), void *data)
97 #ifdef _MSC_VER
98 int rv;
99 rv = _beginthread(func, 0, data);
100 if (rv == (unsigned long) -1)
101 return -1;
102 return 0;
103 #else
104 pid_t pid;
105 pid = fork();
106 if (pid<0)
107 return -1;
108 if (pid==0) {
109 /* Child */
110 func(data);
111 assert(0); /* Should never reach here. */
112 } else {
113 /* Parent */
114 return 0;
116 #endif
119 void spawn_exit()
121 #ifdef _MSC_VER
122 _endthread();
123 #else
124 exit(0);
125 #endif
129 /* Fake socket pair over TCP. Code adapted from perl 5.8.0's util.c */
131 tor_socketpair(int family, int type, int protocol, int fd[2])
133 #ifdef HAVE_SOCKETPAIR_XXX
134 /* For testing purposes, we never fall back to real socketpairs. */
135 return socketpair(family, type, protocol, fd);
136 #else
137 int listener = -1;
138 int connector = -1;
139 int acceptor = -1;
140 struct sockaddr_in listen_addr;
141 struct sockaddr_in connect_addr;
142 size_t size;
144 if (protocol
145 #ifdef AF_UNIX
146 || family != AF_UNIX
147 #endif
149 errno = EAFNOSUPPORT;
150 return -1;
152 if (!fd) {
153 errno = EINVAL;
154 return -1;
157 listener = socket(AF_INET, type, 0);
158 if (listener == -1)
159 return -1;
160 memset (&listen_addr, 0, sizeof (listen_addr));
161 listen_addr.sin_family = AF_INET;
162 listen_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
163 listen_addr.sin_port = 0; /* kernel choses port. */
164 if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
165 == -1)
166 goto tidy_up_and_fail;
167 if (listen(listener, 1) == -1)
168 goto tidy_up_and_fail;
170 connector = socket(AF_INET, type, 0);
171 if (connector == -1)
172 goto tidy_up_and_fail;
173 /* We want to find out the port number to connect to. */
174 size = sizeof (connect_addr);
175 if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
176 goto tidy_up_and_fail;
177 if (size != sizeof (connect_addr))
178 goto abort_tidy_up_and_fail;
179 if (connect(connector, (struct sockaddr *) &connect_addr,
180 sizeof (connect_addr)) == -1)
181 goto tidy_up_and_fail;
183 size = sizeof (listen_addr);
184 acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
185 if (acceptor == -1)
186 goto tidy_up_and_fail;
187 if (size != sizeof(listen_addr))
188 goto abort_tidy_up_and_fail;
189 close(listener);
190 /* Now check we are talking to ourself by matching port and host on the
191 two sockets. */
192 if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
193 goto tidy_up_and_fail;
194 if (size != sizeof (connect_addr)
195 || listen_addr.sin_family != connect_addr.sin_family
196 || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
197 || listen_addr.sin_port != connect_addr.sin_port) {
198 goto abort_tidy_up_and_fail;
200 fd[0] = connector;
201 fd[1] = acceptor;
202 return 0;
204 abort_tidy_up_and_fail:
205 errno = ECONNABORTED; /* I hope this is portable and appropriate. */
206 tidy_up_and_fail:
208 int save_errno = errno;
209 if (listener != -1)
210 close(listener);
211 if (connector != -1)
212 close(connector);
213 if (acceptor != -1)
214 close(acceptor);
215 errno = save_errno;
216 return -1;
218 #endif