1*f4faee91Sderaadt /* $OpenBSD: atomicio.c,v 1.4 2012/12/04 02:24:47 deraadt Exp $ */
25ae6585fSray /*
35ae6585fSray * Copyright (c) 2006 Damien Miller. All rights reserved.
45ae6585fSray * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
55ae6585fSray * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
65ae6585fSray * All rights reserved.
75ae6585fSray *
85ae6585fSray * Redistribution and use in source and binary forms, with or without
95ae6585fSray * modification, are permitted provided that the following conditions
105ae6585fSray * are met:
115ae6585fSray * 1. Redistributions of source code must retain the above copyright
125ae6585fSray * notice, this list of conditions and the following disclaimer.
135ae6585fSray * 2. Redistributions in binary form must reproduce the above copyright
145ae6585fSray * notice, this list of conditions and the following disclaimer in the
155ae6585fSray * documentation and/or other materials provided with the distribution.
165ae6585fSray *
175ae6585fSray * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
185ae6585fSray * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
195ae6585fSray * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
205ae6585fSray * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
215ae6585fSray * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
225ae6585fSray * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235ae6585fSray * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245ae6585fSray * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255ae6585fSray * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
265ae6585fSray * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275ae6585fSray */
285ae6585fSray
295ae6585fSray #include <errno.h>
3062f5b9b7Stobias #include <poll.h>
3162f5b9b7Stobias #include <unistd.h>
325ae6585fSray
335ae6585fSray #include "atomicio.h"
345ae6585fSray
355ae6585fSray /*
365ae6585fSray * ensure all of data on socket comes through. f==read || f==vwrite
375ae6585fSray */
385ae6585fSray size_t
atomicio(ssize_t (* f)(int,void *,size_t),int fd,void * _s,size_t n)395ae6585fSray atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
405ae6585fSray {
415ae6585fSray char *s = _s;
425ae6585fSray size_t pos = 0;
435ae6585fSray ssize_t res;
4462f5b9b7Stobias struct pollfd pfd;
455ae6585fSray
4662f5b9b7Stobias pfd.fd = fd;
4762f5b9b7Stobias pfd.events = f == read ? POLLIN : POLLOUT;
485ae6585fSray while (n > pos) {
495ae6585fSray res = (f) (fd, s + pos, n - pos);
505ae6585fSray switch (res) {
515ae6585fSray case -1:
5262f5b9b7Stobias if (errno == EINTR)
535ae6585fSray continue;
5462f5b9b7Stobias if (errno == EAGAIN) {
5562f5b9b7Stobias (void)poll(&pfd, 1, -1);
5662f5b9b7Stobias continue;
5762f5b9b7Stobias }
585ae6585fSray return 0;
595ae6585fSray case 0:
605ae6585fSray errno = EPIPE;
615ae6585fSray return pos;
625ae6585fSray default:
635ae6585fSray pos += (size_t)res;
645ae6585fSray }
655ae6585fSray }
665ae6585fSray return (pos);
675ae6585fSray }
68