diff options
author | djm@openbsd.org <djm@openbsd.org> | 2019-01-23 02:01:10 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-01-23 13:02:50 +1100 |
commit | 2c223878e53cc46def760add459f5f7c4fb43e35 (patch) | |
tree | 0679838120920cdd4b2272cb6edfd8dce508ae22 /ssh-pkcs11-helper.c | |
parent | bb956eaa94757ad058ff43631c3a7d6c94d38c2f (diff) |
upstream: switch mainloop from select(2) to poll(2); ok deraadt@
OpenBSD-Commit-ID: 37645419a330037d297f6f0adc3b3663e7ae7b2e
Diffstat (limited to 'ssh-pkcs11-helper.c')
-rw-r--r-- | ssh-pkcs11-helper.c | 42 |
1 files changed, 19 insertions, 23 deletions
diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index c7dfea279..97fb1212c 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-pkcs11-helper.c,v 1.16 2019/01/21 12:53:35 djm Exp $ */ | 1 | /* $OpenBSD: ssh-pkcs11-helper.c,v 1.17 2019/01/23 02:01:10 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2010 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2010 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -24,10 +24,11 @@ | |||
24 | 24 | ||
25 | #include "openbsd-compat/sys-queue.h" | 25 | #include "openbsd-compat/sys-queue.h" |
26 | 26 | ||
27 | #include <errno.h> | ||
28 | #include <poll.h> | ||
27 | #include <stdarg.h> | 29 | #include <stdarg.h> |
28 | #include <string.h> | 30 | #include <string.h> |
29 | #include <unistd.h> | 31 | #include <unistd.h> |
30 | #include <errno.h> | ||
31 | 32 | ||
32 | #include "xmalloc.h" | 33 | #include "xmalloc.h" |
33 | #include "sshbuf.h" | 34 | #include "sshbuf.h" |
@@ -311,14 +312,13 @@ cleanup_exit(int i) | |||
311 | int | 312 | int |
312 | main(int argc, char **argv) | 313 | main(int argc, char **argv) |
313 | { | 314 | { |
314 | fd_set *rset, *wset; | ||
315 | int r, ch, in, out, max, log_stderr = 0; | 315 | int r, ch, in, out, max, log_stderr = 0; |
316 | ssize_t len, olen, set_size; | 316 | ssize_t len; |
317 | SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; | 317 | SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; |
318 | LogLevel log_level = SYSLOG_LEVEL_ERROR; | 318 | LogLevel log_level = SYSLOG_LEVEL_ERROR; |
319 | char buf[4*4096]; | 319 | char buf[4*4096]; |
320 | |||
321 | extern char *__progname; | 320 | extern char *__progname; |
321 | struct pollfd pfd[2]; | ||
322 | 322 | ||
323 | ssh_malloc_init(); /* must be called before any mallocs */ | 323 | ssh_malloc_init(); /* must be called before any mallocs */ |
324 | __progname = ssh_get_progname(argv[0]); | 324 | __progname = ssh_get_progname(argv[0]); |
@@ -360,13 +360,10 @@ main(int argc, char **argv) | |||
360 | if ((oqueue = sshbuf_new()) == NULL) | 360 | if ((oqueue = sshbuf_new()) == NULL) |
361 | fatal("%s: sshbuf_new failed", __func__); | 361 | fatal("%s: sshbuf_new failed", __func__); |
362 | 362 | ||
363 | set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask); | 363 | while (1) { |
364 | rset = xmalloc(set_size); | 364 | memset(pfd, 0, sizeof(pfd)); |
365 | wset = xmalloc(set_size); | 365 | pfd[0].fd = in; |
366 | 366 | pfd[1].fd = out; | |
367 | for (;;) { | ||
368 | memset(rset, 0, set_size); | ||
369 | memset(wset, 0, set_size); | ||
370 | 367 | ||
371 | /* | 368 | /* |
372 | * Ensure that we can read a full buffer and handle | 369 | * Ensure that we can read a full buffer and handle |
@@ -375,23 +372,21 @@ main(int argc, char **argv) | |||
375 | */ | 372 | */ |
376 | if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 && | 373 | if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 && |
377 | (r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0) | 374 | (r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0) |
378 | FD_SET(in, rset); | 375 | pfd[0].events = POLLIN; |
379 | else if (r != SSH_ERR_NO_BUFFER_SPACE) | 376 | else if (r != SSH_ERR_NO_BUFFER_SPACE) |
380 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 377 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
381 | 378 | ||
382 | olen = sshbuf_len(oqueue); | 379 | if (sshbuf_len(oqueue) > 0) |
383 | if (olen > 0) | 380 | pfd[1].events = POLLOUT; |
384 | FD_SET(out, wset); | ||
385 | 381 | ||
386 | if (select(max+1, rset, wset, NULL, NULL) < 0) { | 382 | if ((r = poll(pfd, 2, -1 /* INFTIM */)) <= 0) { |
387 | if (errno == EINTR) | 383 | if (r == 0 || errno == EINTR) |
388 | continue; | 384 | continue; |
389 | error("select: %s", strerror(errno)); | 385 | fatal("poll: %s", strerror(errno)); |
390 | cleanup_exit(2); | ||
391 | } | 386 | } |
392 | 387 | ||
393 | /* copy stdin to iqueue */ | 388 | /* copy stdin to iqueue */ |
394 | if (FD_ISSET(in, rset)) { | 389 | if ((pfd[0].revents & (POLLIN|POLLERR)) != 0) { |
395 | len = read(in, buf, sizeof buf); | 390 | len = read(in, buf, sizeof buf); |
396 | if (len == 0) { | 391 | if (len == 0) { |
397 | debug("read eof"); | 392 | debug("read eof"); |
@@ -405,8 +400,9 @@ main(int argc, char **argv) | |||
405 | } | 400 | } |
406 | } | 401 | } |
407 | /* send oqueue to stdout */ | 402 | /* send oqueue to stdout */ |
408 | if (FD_ISSET(out, wset)) { | 403 | if ((pfd[1].revents & (POLLOUT|POLLHUP)) != 0) { |
409 | len = write(out, sshbuf_ptr(oqueue), olen); | 404 | len = write(out, sshbuf_ptr(oqueue), |
405 | sshbuf_len(oqueue)); | ||
410 | if (len < 0) { | 406 | if (len < 0) { |
411 | error("write: %s", strerror(errno)); | 407 | error("write: %s", strerror(errno)); |
412 | cleanup_exit(1); | 408 | cleanup_exit(1); |