1249499Sdelphij/* $OpenBSD: atomicio.c,v 1.11 2012/12/04 02:24:47 deraadt Exp $ */ 2141261Sdelphij/* 3178382Sdelphij * Copyright (c) 2006 Damien Miller. All rights reserved. 4178382Sdelphij * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. 5141261Sdelphij * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. 6141261Sdelphij * All rights reserved. 7141261Sdelphij * 8141261Sdelphij * Redistribution and use in source and binary forms, with or without 9141261Sdelphij * modification, are permitted provided that the following conditions 10141261Sdelphij * are met: 11141261Sdelphij * 1. Redistributions of source code must retain the above copyright 12141261Sdelphij * notice, this list of conditions and the following disclaimer. 13141261Sdelphij * 2. Redistributions in binary form must reproduce the above copyright 14141261Sdelphij * notice, this list of conditions and the following disclaimer in the 15141261Sdelphij * documentation and/or other materials provided with the distribution. 16141261Sdelphij * 17141261Sdelphij * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18141261Sdelphij * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19141261Sdelphij * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20141261Sdelphij * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21141261Sdelphij * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22141261Sdelphij * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23141261Sdelphij * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24141261Sdelphij * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25141261Sdelphij * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26141261Sdelphij * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27141261Sdelphij */ 28141261Sdelphij 29141261Sdelphij#include <errno.h> 30178382Sdelphij#include <poll.h> 31141261Sdelphij#include <unistd.h> 32178382Sdelphij 33158795Sdelphij#include "atomicio.h" 34141261Sdelphij 35141261Sdelphij/* 36158795Sdelphij * ensure all of data on socket comes through. f==read || f==vwrite 37141261Sdelphij */ 38158795Sdelphijsize_t 39178382Sdelphijatomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) 40141261Sdelphij{ 41141261Sdelphij char *s = _s; 42158795Sdelphij size_t pos = 0; 43158795Sdelphij ssize_t res; 44178382Sdelphij struct pollfd pfd; 45141261Sdelphij 46178382Sdelphij pfd.fd = fd; 47178382Sdelphij pfd.events = f == read ? POLLIN : POLLOUT; 48141261Sdelphij while (n > pos) { 49141261Sdelphij res = (f) (fd, s + pos, n - pos); 50141261Sdelphij switch (res) { 51141261Sdelphij case -1: 52178382Sdelphij if (errno == EINTR) 53141261Sdelphij continue; 54221793Sdelphij if ((errno == EAGAIN) || (errno == ENOBUFS)) { 55178382Sdelphij (void)poll(&pfd, 1, -1); 56178382Sdelphij continue; 57178382Sdelphij } 58158795Sdelphij return 0; 59141261Sdelphij case 0: 60158795Sdelphij errno = EPIPE; 61158795Sdelphij return pos; 62141261Sdelphij default: 63158795Sdelphij pos += (size_t)res; 64141261Sdelphij } 65141261Sdelphij } 66178382Sdelphij return (pos); 67141261Sdelphij} 68