atomicio.c revision 221793
1221793Sdelphij/* $OpenBSD: atomicio.c,v 1.10 2011/01/08 00:47:19 jeremy 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 29178382Sdelphij#include <sys/param.h> 30178382Sdelphij 31141261Sdelphij#include <errno.h> 32178382Sdelphij#include <poll.h> 33141261Sdelphij#include <unistd.h> 34178382Sdelphij 35158795Sdelphij#include "atomicio.h" 36141261Sdelphij 37141261Sdelphij/* 38158795Sdelphij * ensure all of data on socket comes through. f==read || f==vwrite 39141261Sdelphij */ 40158795Sdelphijsize_t 41178382Sdelphijatomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) 42141261Sdelphij{ 43141261Sdelphij char *s = _s; 44158795Sdelphij size_t pos = 0; 45158795Sdelphij ssize_t res; 46178382Sdelphij struct pollfd pfd; 47141261Sdelphij 48178382Sdelphij pfd.fd = fd; 49178382Sdelphij pfd.events = f == read ? POLLIN : POLLOUT; 50141261Sdelphij while (n > pos) { 51141261Sdelphij res = (f) (fd, s + pos, n - pos); 52141261Sdelphij switch (res) { 53141261Sdelphij case -1: 54178382Sdelphij if (errno == EINTR) 55141261Sdelphij continue; 56221793Sdelphij if ((errno == EAGAIN) || (errno == ENOBUFS)) { 57178382Sdelphij (void)poll(&pfd, 1, -1); 58178382Sdelphij continue; 59178382Sdelphij } 60158795Sdelphij return 0; 61141261Sdelphij case 0: 62158795Sdelphij errno = EPIPE; 63158795Sdelphij return pos; 64141261Sdelphij default: 65158795Sdelphij pos += (size_t)res; 66141261Sdelphij } 67141261Sdelphij } 68178382Sdelphij return (pos); 69141261Sdelphij} 70