aboutsummaryrefslogtreecommitdiff
path: root/src/gns/nss/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/nss/util.c')
-rw-r--r--src/gns/nss/util.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/src/gns/nss/util.c b/src/gns/nss/util.c
new file mode 100644
index 000000000..7349d6b1f
--- /dev/null
+++ b/src/gns/nss/util.c
@@ -0,0 +1,207 @@
1/* $Id$ */
2
3/***
4 This file is part of nss-mdns.
5
6 nss-mdns is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 nss-mdns is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with nss-mdns; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20***/
21
22#include <gnunet_config.h>
23
24#include <sys/select.h>
25#include <errno.h>
26#include <string.h>
27#include <assert.h>
28#include <fcntl.h>
29
30#include "util.h"
31
32#ifdef ENABLE_LEGACY
33
34/* Calculate the difference between the two specfified timeval
35 * timestamsps. */
36usec_t timeval_diff(const struct timeval *a, const struct timeval *b) {
37 usec_t r;
38 assert(a && b);
39
40 /* Check which whan is the earlier time and swap the two arguments if reuqired. */
41 if (timeval_cmp(a, b) < 0) {
42 const struct timeval *c;
43 c = a;
44 a = b;
45 b = c;
46 }
47
48 /* Calculate the second difference*/
49 r = ((usec_t) a->tv_sec - b->tv_sec)* 1000000;
50
51 /* Calculate the microsecond difference */
52 if (a->tv_usec > b->tv_usec)
53 r += ((usec_t) a->tv_usec - b->tv_usec);
54 else if (a->tv_usec < b->tv_usec)
55 r -= ((usec_t) b->tv_usec - a->tv_usec);
56
57 return r;
58}
59
60/* Compare the two timeval structs and return 0 when equal, negative when a < b, positive otherwse */
61int timeval_cmp(const struct timeval *a, const struct timeval *b) {
62 assert(a && b);
63
64 if (a->tv_sec < b->tv_sec)
65 return -1;
66
67 if (a->tv_sec > b->tv_sec)
68 return 1;
69
70 if (a->tv_usec < b->tv_usec)
71 return -1;
72
73 if (a->tv_usec > b->tv_usec)
74 return 1;
75
76 return 0;
77}
78
79/* Return the time difference between now and the specified timestamp */
80usec_t timeval_age(const struct timeval *tv) {
81 struct timeval now;
82 assert(tv);
83 gettimeofday(&now, NULL);
84 return timeval_diff(&now, tv);
85}
86
87/* Add the specified time inmicroseconds to the specified timeval structure */
88void timeval_add(struct timeval *tv, usec_t v) {
89 unsigned long secs;
90 assert(tv);
91
92 secs = (v/1000000);
93 tv->tv_sec += (unsigned long) secs;
94 v -= secs*1000000;
95
96 tv->tv_usec += v;
97
98 /* Normalize */
99 while (tv->tv_usec >= 1000000) {
100 tv->tv_sec++;
101 tv->tv_usec -= 1000000;
102 }
103}
104
105int set_nonblock(int fd) {
106 int n;
107 assert(fd >= 0);
108
109 if ((n = fcntl(fd, F_GETFL)) < 0)
110 return -1;
111
112 if (n & O_NONBLOCK)
113 return 0;
114
115 return fcntl(fd, F_SETFL, n|O_NONBLOCK);
116}
117
118int wait_for_write(int fd, struct timeval *end) {
119 struct timeval now;
120
121 if (end)
122 gettimeofday(&now, NULL);
123
124 for (;;) {
125 struct timeval tv;
126 fd_set fds;
127 int r;
128
129 FD_ZERO(&fds);
130 FD_SET(fd, &fds);
131
132 if (end) {
133 if (timeval_cmp(&now, end) >= 0)
134 return 1;
135
136 tv.tv_sec = tv.tv_usec = 0;
137 timeval_add(&tv, timeval_diff(end, &now));
138 }
139
140 if ((r = select(fd+1, NULL, &fds, NULL, end ? &tv : NULL)) < 0) {
141 if (errno != EINTR)
142 return -1;
143 } else if (r == 0)
144 return 1;
145 else {
146 if (FD_ISSET(fd, &fds))
147 return 0;
148 }
149
150 if (end)
151 gettimeofday(&now, NULL);
152 }
153}
154
155int wait_for_read(int fd, struct timeval *end) {
156 struct timeval now;
157
158 if (end)
159 gettimeofday(&now, NULL);
160
161 for (;;) {
162 struct timeval tv;
163 fd_set fds;
164 int r;
165
166 FD_ZERO(&fds);
167 FD_SET(fd, &fds);
168
169 if (end) {
170 if (timeval_cmp(&now, end) >= 0)
171 return 1;
172
173 tv.tv_sec = tv.tv_usec = 0;
174 timeval_add(&tv, timeval_diff(end, &now));
175 }
176
177 if ((r = select(fd+1, &fds, NULL, NULL, end ? &tv : NULL)) < 0) {
178 if (errno != EINTR)
179 return -1;
180 } else if (r == 0)
181 return 1;
182 else {
183
184 if (FD_ISSET(fd, &fds))
185 return 0;
186 }
187
188 if (end)
189 gettimeofday(&now, NULL);
190 }
191}
192
193#endif
194
195int set_cloexec(int fd) {
196 int n;
197 assert(fd >= 0);
198
199 if ((n = fcntl(fd, F_GETFD)) < 0)
200 return -1;
201
202 if (n & FD_CLOEXEC)
203 return 0;
204
205 return fcntl(fd, F_SETFD, n|FD_CLOEXEC);
206}
207