1e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* $OpenBSD: atomicio.c,v 1.10 2011/01/08 00:47:19 jeremy Exp $ */ 2e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* 3e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Copyright (c) 2006 Damien Miller. All rights reserved. 4e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. 5e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. 6e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * All rights reserved. 7e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * 8e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * Redistribution and use in source and binary forms, with or without 9e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * modification, are permitted provided that the following conditions 10e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * are met: 11e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * 1. Redistributions of source code must retain the above copyright 12e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * notice, this list of conditions and the following disclaimer. 13e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * 2. Redistributions in binary form must reproduce the above copyright 14e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * notice, this list of conditions and the following disclaimer in the 15e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * documentation and/or other materials provided with the distribution. 16e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * 17e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 28e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 29e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <sys/param.h> 30e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 31e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <errno.h> 32e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <poll.h> 33e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include <unistd.h> 34e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 35e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich#include "atomicio.h" 36e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 37e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich/* 38e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich * ensure all of data on socket comes through. f==read || f==vwrite 39e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich */ 40e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichsize_t 41e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevichatomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) 42e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich{ 43e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich char *s = _s; 44e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich size_t pos = 0; 45e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich ssize_t res; 46e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich struct pollfd pfd; 47e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich 48e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pfd.fd = fd; 49e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pfd.events = f == read ? POLLIN : POLLOUT; 50e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich while (n > pos) { 51e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich res = (f) (fd, s + pos, n - pos); 52e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich switch (res) { 53e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case -1: 54e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if (errno == EINTR) 55e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich continue; 56e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich if ((errno == EAGAIN) || (errno == ENOBUFS)) { 57e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich (void)poll(&pfd, 1, -1); 58e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich continue; 59e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 60e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return 0; 61e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich case 0: 62e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich errno = EPIPE; 63e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return pos; 64e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich default: 65e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich pos += (size_t)res; 66e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 67e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich } 68e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich return (pos); 69e4e83f8147f92141cd02cc46cccca088c527ea2aNick Kralevich} 70