summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c93
1 files changed, 87 insertions, 6 deletions
diff --git a/misc.c b/misc.c
index bdc06fdb3..009e02bc5 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: misc.c,v 1.133 2018/10/05 14:26:09 naddy Exp $ */ 1/* $OpenBSD: misc.c,v 1.137 2019/01/23 21:50:56 dtucker Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved. 4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -38,6 +38,7 @@
38#ifdef HAVE_LIBGEN_H 38#ifdef HAVE_LIBGEN_H
39# include <libgen.h> 39# include <libgen.h>
40#endif 40#endif
41#include <poll.h>
41#include <signal.h> 42#include <signal.h>
42#include <stdarg.h> 43#include <stdarg.h>
43#include <stdio.h> 44#include <stdio.h>
@@ -234,6 +235,80 @@ set_rdomain(int fd, const char *name)
234#endif 235#endif
235} 236}
236 237
238/*
239 * Wait up to *timeoutp milliseconds for fd to be readable. Updates
240 * *timeoutp with time remaining.
241 * Returns 0 if fd ready or -1 on timeout or error (see errno).
242 */
243int
244waitrfd(int fd, int *timeoutp)
245{
246 struct pollfd pfd;
247 struct timeval t_start;
248 int oerrno, r;
249
250 monotime_tv(&t_start);
251 pfd.fd = fd;
252 pfd.events = POLLIN;
253 for (; *timeoutp >= 0;) {
254 r = poll(&pfd, 1, *timeoutp);
255 oerrno = errno;
256 ms_subtract_diff(&t_start, timeoutp);
257 errno = oerrno;
258 if (r > 0)
259 return 0;
260 else if (r == -1 && errno != EAGAIN)
261 return -1;
262 else if (r == 0)
263 break;
264 }
265 /* timeout */
266 errno = ETIMEDOUT;
267 return -1;
268}
269
270/*
271 * Attempt a non-blocking connect(2) to the specified address, waiting up to
272 * *timeoutp milliseconds for the connection to complete. If the timeout is
273 * <=0, then wait indefinitely.
274 *
275 * Returns 0 on success or -1 on failure.
276 */
277int
278timeout_connect(int sockfd, const struct sockaddr *serv_addr,
279 socklen_t addrlen, int *timeoutp)
280{
281 int optval = 0;
282 socklen_t optlen = sizeof(optval);
283
284 /* No timeout: just do a blocking connect() */
285 if (timeoutp == NULL || *timeoutp <= 0)
286 return connect(sockfd, serv_addr, addrlen);
287
288 set_nonblock(sockfd);
289 if (connect(sockfd, serv_addr, addrlen) == 0) {
290 /* Succeeded already? */
291 unset_nonblock(sockfd);
292 return 0;
293 } else if (errno != EINPROGRESS)
294 return -1;
295
296 if (waitrfd(sockfd, timeoutp) == -1)
297 return -1;
298
299 /* Completed or failed */
300 if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) {
301 debug("getsockopt: %s", strerror(errno));
302 return -1;
303 }
304 if (optval != 0) {
305 errno = optval;
306 return -1;
307 }
308 unset_nonblock(sockfd);
309 return 0;
310}
311
237/* Characters considered whitespace in strsep calls. */ 312/* Characters considered whitespace in strsep calls. */
238#define WHITESPACE " \t\r\n" 313#define WHITESPACE " \t\r\n"
239#define QUOTE "\"" 314#define QUOTE "\""
@@ -489,7 +564,7 @@ put_host_port(const char *host, u_short port)
489 * The delimiter char, if present, is stored in delim. 564 * The delimiter char, if present, is stored in delim.
490 * If this is the last field, *cp is set to NULL. 565 * If this is the last field, *cp is set to NULL.
491 */ 566 */
492static char * 567char *
493hpdelim2(char **cp, char *delim) 568hpdelim2(char **cp, char *delim)
494{ 569{
495 char *s, *old; 570 char *s, *old;
@@ -1335,11 +1410,11 @@ bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen)
1335{ 1410{
1336 bw->buflen = buflen; 1411 bw->buflen = buflen;
1337 bw->rate = kbps; 1412 bw->rate = kbps;
1338 bw->thresh = bw->rate; 1413 bw->thresh = buflen;
1339 bw->lamt = 0; 1414 bw->lamt = 0;
1340 timerclear(&bw->bwstart); 1415 timerclear(&bw->bwstart);
1341 timerclear(&bw->bwend); 1416 timerclear(&bw->bwend);
1342} 1417}
1343 1418
1344/* Callback from read/write loop to insert bandwidth-limiting delays */ 1419/* Callback from read/write loop to insert bandwidth-limiting delays */
1345void 1420void
@@ -1348,12 +1423,11 @@ bandwidth_limit(struct bwlimit *bw, size_t read_len)
1348 u_int64_t waitlen; 1423 u_int64_t waitlen;
1349 struct timespec ts, rm; 1424 struct timespec ts, rm;
1350 1425
1426 bw->lamt += read_len;
1351 if (!timerisset(&bw->bwstart)) { 1427 if (!timerisset(&bw->bwstart)) {
1352 monotime_tv(&bw->bwstart); 1428 monotime_tv(&bw->bwstart);
1353 return; 1429 return;
1354 } 1430 }
1355
1356 bw->lamt += read_len;
1357 if (bw->lamt < bw->thresh) 1431 if (bw->lamt < bw->thresh)
1358 return; 1432 return;
1359 1433
@@ -2037,3 +2111,10 @@ format_absolute_time(uint64_t t, char *buf, size_t len)
2037 localtime_r(&tt, &tm); 2111 localtime_r(&tt, &tm);
2038 strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm); 2112 strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm);
2039} 2113}
2114
2115/* check if path is absolute */
2116int
2117path_absolute(const char *path)
2118{
2119 return (*path == '/') ? 1 : 0;
2120}