diff options
author | Alistair Delva <adelva@google.com> | 2020-08-20 16:14:23 -0700 |
---|---|---|
committer | Alistair Delva <adelva@google.com> | 2020-08-20 16:53:18 -0700 |
commit | d9da10d147d633fdb6ec65e17ff4b8447419d83e (patch) | |
tree | 8f93e8fdc2907f141e0924910bfec26669819f0b /atomicio.c | |
parent | 22246b08952d746a7cc5a292570636cf4277598f (diff) | |
parent | ecb2c02d994b3e21994f31a70ff911667c262f1f (diff) |
Merge upstream-master into master
Commit ecb2c02d994b3e21994f31a70ff911667c262f1f upstream
This nearly (but not quite) corresponds to V_8_3_P1; subsequent
cherry-picks will correct this.
Bug: 162492243
Change-Id: I3c079d86435b7c25aefff4538dc89a3002b1e25b
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; |