diff options
author | Alistair Delva <adelva@google.com> | 2020-08-21 00:00:13 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-08-21 00:00:13 +0000 |
commit | ed358b3546c776c1c677fd88eb8f716cf6187510 (patch) | |
tree | 3c6134bcb2cda4b9dccc57b4a8b997a945aab62d /atomicio.c | |
parent | 22246b08952d746a7cc5a292570636cf4277598f (diff) | |
parent | 44a1065de8a58c51a021243a28bfa01e87822e4f (diff) |
Merge changes I934c73d4,I28cdc9a0,I9e734da9,I3c079d86
* changes:
UPSTREAM: depend
UPSTREAM: upstream: avoid possible NULL deref; from Pedro Martelletto
Revert "upstream: fix compilation with DEBUG_KEXDH; bz#3160 ok dtucker@"
Merge upstream-master into master
Diffstat (limited to 'atomicio.c')
-rw-r--r-- | atomicio.c | 36 |
1 files changed, 23 insertions, 13 deletions
@@ -1,4 +1,4 @@ -/* $OpenBSD: atomicio.c,v 1.27 2015/01/16 06:40:12 deraadt Exp $ */ +/* $OpenBSD: atomicio.c,v 1.30 2019/01/24 02:42:23 dtucker Exp $ */ /* * Copyright (c) 2006 Damien Miller. All rights reserved. * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. @@ -57,20 +57,25 @@ atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n, ssize_t res; struct pollfd pfd; -#ifndef BROKEN_READ_COMPARISON pfd.fd = fd; +#ifndef BROKEN_READ_COMPARISON pfd.events = f == read ? POLLIN : POLLOUT; +#else + pfd.events = POLLIN|POLLOUT; #endif while (n > pos) { res = (f) (fd, s + pos, n - pos); switch (res) { case -1: - if (errno == EINTR) + if (errno == EINTR) { + /* possible SIGALARM, update callback */ + if (cb != NULL && cb(cb_arg, 0) == -1) { + errno = EINTR; + return pos; + } continue; - if (errno == EAGAIN || errno == EWOULDBLOCK) { -#ifndef BROKEN_READ_COMPARISON + } else if (errno == EAGAIN || errno == EWOULDBLOCK) { (void)poll(&pfd, 1, -1); -#endif continue; } return 0; @@ -107,27 +112,32 @@ atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd, struct iovec iov_array[IOV_MAX], *iov = iov_array; struct pollfd pfd; - if (iovcnt > IOV_MAX) { + if (iovcnt < 0 || iovcnt > IOV_MAX) { errno = EINVAL; return 0; } /* Make a copy of the iov array because we may modify it below */ - memcpy(iov, _iov, iovcnt * sizeof(*_iov)); + memcpy(iov, _iov, (size_t)iovcnt * sizeof(*_iov)); -#ifndef BROKEN_READV_COMPARISON pfd.fd = fd; +#ifndef BROKEN_READV_COMPARISON pfd.events = f == readv ? POLLIN : POLLOUT; +#else + pfd.events = POLLIN|POLLOUT; #endif for (; iovcnt > 0 && iov[0].iov_len > 0;) { res = (f) (fd, iov, iovcnt); switch (res) { case -1: - if (errno == EINTR) + if (errno == EINTR) { + /* possible SIGALARM, update callback */ + if (cb != NULL && cb(cb_arg, 0) == -1) { + errno = EINTR; + return pos; + } continue; - if (errno == EAGAIN || errno == EWOULDBLOCK) { -#ifndef BROKEN_READV_COMPARISON + } else if (errno == EAGAIN || errno == EWOULDBLOCK) { (void)poll(&pfd, 1, -1); -#endif continue; } return 0; |