diff options
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 69 |
1 files changed, 63 insertions, 6 deletions
@@ -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 | */ |
244 | int | 246 | static int |
245 | waitrfd(int fd, int *timeoutp) | 247 | waitfd(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 | */ | ||
278 | int | ||
279 | waitrfd(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 | */ | ||
1302 | void | ||
1303 | xextendf(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 | |||
1285 | u_int64_t | 1324 | u_int64_t |
1286 | get_u64(const void *vp) | 1325 | get_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 | ||
2300 | sshsig_t | ||
2301 | ssh_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 | } | ||