summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c69
1 files changed, 63 insertions, 6 deletions
diff --git a/misc.c b/misc.c
index 42eeb425a..073d3be19 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: misc.c,v 1.142 2019/09/03 08:32:11 djm Exp $ */ 1/* $OpenBSD: misc.c,v 1.146 2020/01/28 01:49:36 djm 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,7 +38,9 @@
38#ifdef HAVE_LIBGEN_H 38#ifdef HAVE_LIBGEN_H
39# include <libgen.h> 39# include <libgen.h>
40#endif 40#endif
41#ifdef HAVE_POLL_H
41#include <poll.h> 42#include <poll.h>
43#endif
42#include <signal.h> 44#include <signal.h>
43#include <stdarg.h> 45#include <stdarg.h>
44#include <stdio.h> 46#include <stdio.h>
@@ -237,12 +239,12 @@ set_rdomain(int fd, const char *name)
237} 239}
238 240
239/* 241/*
240 * Wait up to *timeoutp milliseconds for fd to be readable. Updates 242 * Wait up to *timeoutp milliseconds for events on fd. Updates
241 * *timeoutp with time remaining. 243 * *timeoutp with time remaining.
242 * Returns 0 if fd ready or -1 on timeout or error (see errno). 244 * Returns 0 if fd ready or -1 on timeout or error (see errno).
243 */ 245 */
244int 246static int
245waitrfd(int fd, int *timeoutp) 247waitfd(int fd, int *timeoutp, short events)
246{ 248{
247 struct pollfd pfd; 249 struct pollfd pfd;
248 struct timeval t_start; 250 struct timeval t_start;
@@ -250,7 +252,7 @@ waitrfd(int fd, int *timeoutp)
250 252
251 monotime_tv(&t_start); 253 monotime_tv(&t_start);
252 pfd.fd = fd; 254 pfd.fd = fd;
253 pfd.events = POLLIN; 255 pfd.events = events;
254 for (; *timeoutp >= 0;) { 256 for (; *timeoutp >= 0;) {
255 r = poll(&pfd, 1, *timeoutp); 257 r = poll(&pfd, 1, *timeoutp);
256 oerrno = errno; 258 oerrno = errno;
@@ -269,6 +271,16 @@ waitrfd(int fd, int *timeoutp)
269} 271}
270 272
271/* 273/*
274 * Wait up to *timeoutp milliseconds for fd to be readable. Updates
275 * *timeoutp with time remaining.
276 * Returns 0 if fd ready or -1 on timeout or error (see errno).
277 */
278int
279waitrfd(int fd, int *timeoutp) {
280 return waitfd(fd, timeoutp, POLLIN);
281}
282
283/*
272 * Attempt a non-blocking connect(2) to the specified address, waiting up to 284 * Attempt a non-blocking connect(2) to the specified address, waiting up to
273 * *timeoutp milliseconds for the connection to complete. If the timeout is 285 * *timeoutp milliseconds for the connection to complete. If the timeout is
274 * <=0, then wait indefinitely. 286 * <=0, then wait indefinitely.
@@ -294,7 +306,7 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
294 } else if (errno != EINPROGRESS) 306 } else if (errno != EINPROGRESS)
295 return -1; 307 return -1;
296 308
297 if (waitrfd(sockfd, timeoutp) == -1) 309 if (waitfd(sockfd, timeoutp, POLLIN | POLLOUT) == -1)
298 return -1; 310 return -1;
299 311
300 /* Completed or failed */ 312 /* Completed or failed */
@@ -1282,6 +1294,33 @@ tohex(const void *vp, size_t l)
1282 return (r); 1294 return (r);
1283} 1295}
1284 1296
1297/*
1298 * Extend string *sp by the specified format. If *sp is not NULL (or empty),
1299 * then the separator 'sep' will be prepended before the formatted arguments.
1300 * Extended strings are heap allocated.
1301 */
1302void
1303xextendf(char **sp, const char *sep, const char *fmt, ...)
1304{
1305 va_list ap;
1306 char *tmp1, *tmp2;
1307
1308 va_start(ap, fmt);
1309 xvasprintf(&tmp1, fmt, ap);
1310 va_end(ap);
1311
1312 if (*sp == NULL || **sp == '\0') {
1313 free(*sp);
1314 *sp = tmp1;
1315 return;
1316 }
1317 xasprintf(&tmp2, "%s%s%s", *sp, sep == NULL ? "" : sep, tmp1);
1318 free(tmp1);
1319 free(*sp);
1320 *sp = tmp2;
1321}
1322
1323
1285u_int64_t 1324u_int64_t
1286get_u64(const void *vp) 1325get_u64(const void *vp)
1287{ 1326{
@@ -1570,6 +1609,7 @@ static const struct {
1570 { "cs6", IPTOS_DSCP_CS6 }, 1609 { "cs6", IPTOS_DSCP_CS6 },
1571 { "cs7", IPTOS_DSCP_CS7 }, 1610 { "cs7", IPTOS_DSCP_CS7 },
1572 { "ef", IPTOS_DSCP_EF }, 1611 { "ef", IPTOS_DSCP_EF },
1612 { "le", IPTOS_DSCP_LE },
1573 { "lowdelay", IPTOS_LOWDELAY }, 1613 { "lowdelay", IPTOS_LOWDELAY },
1574 { "throughput", IPTOS_THROUGHPUT }, 1614 { "throughput", IPTOS_THROUGHPUT },
1575 { "reliability", IPTOS_RELIABILITY }, 1615 { "reliability", IPTOS_RELIABILITY },
@@ -2257,3 +2297,20 @@ opt_match(const char **opts, const char *term)
2257 return 0; 2297 return 0;
2258} 2298}
2259 2299
2300sshsig_t
2301ssh_signal(int signum, sshsig_t handler)
2302{
2303 struct sigaction sa, osa;
2304
2305 /* mask all other signals while in handler */
2306 bzero(&sa, sizeof(sa));
2307 sa.sa_handler = handler;
2308 sigfillset(&sa.sa_mask);
2309 if (signum != SIGALRM)
2310 sa.sa_flags = SA_RESTART;
2311 if (sigaction(signum, &sa, &osa) == -1) {
2312 debug3("sigaction(%s): %s", strsignal(signum), strerror(errno));
2313 return SIG_ERR;
2314 }
2315 return osa.sa_handler;
2316}