1c3aae25116e66c177579b0b79182b09340b19753Chris Lattner/* $OpenBSD: atomicio.c,v 1.10 2011/01/08 00:47:19 jeremy Exp $ */ 2ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman/* 36fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell * Copyright (c) 2006 Damien Miller. All rights reserved. 46fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner * All rights reserved. 7ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman * 86fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell * Redistribution and use in source and binary forms, with or without 9ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman * modification, are permitted provided that the following conditions 10c3aae25116e66c177579b0b79182b09340b19753Chris Lattner * are met: 11c3aae25116e66c177579b0b79182b09340b19753Chris Lattner * 1. Redistributions of source code must retain the above copyright 12ea61c358720aa6c7a159d51658b34276316aa841Misha Brukman * notice, this list of conditions and the following disclaimer. 13cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner * 2. Redistributions in binary form must reproduce the above copyright 14cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner * notice, this list of conditions and the following disclaimer in the 15cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner * documentation and/or other materials provided with the distribution. 16cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner * 17cacf462915344c2af25eef1af1f3ee2c7280ff56Chris Lattner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20583bd47f777fe3eb8305872fa0eadab31e833dffJim Laskey * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 214b84086e89d86fb16f562166d9fea8df37db6be7Dan Gohman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22583bd47f777fe3eb8305872fa0eadab31e833dffJim Laskey * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23b80e2be8894db9f843f32ebaffb9b7fd6b57d206Chris Lattner * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24acaf09dbe4a6781163857db1321bbd5795e7d410Dan Gohman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255892d47a625638a90afeb31dd4f6f80a2f9bacdeChris Lattner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26322812e603705e1c2037313633e72f689524b163Evan Cheng * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27eb19e40efbd3cae80c908a30cdf4d33450733c45Chris Lattner */ 28d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 29d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke#include <sys/param.h> 30fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman 31fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman#include <errno.h> 32fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman#include <poll.h> 33fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman#include <unistd.h> 34fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman 356e7a1617ac4a34792d9097b8d3644b72f57a45f7Devang Patel#include "atomicio.h" 36fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman 37fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman/* 38fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman * ensure all of data on socket comes through. f==read || f==vwrite 39fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman */ 408e4018e2de52c534405d7155c7009d0b35afb861Cedric Venetsize_t 418e4018e2de52c534405d7155c7009d0b35afb861Cedric Venetatomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) 42c7f6b8c5d40e17bf43fd3a1549d7d89c9da735e1Gabor Greif{ 43fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman char *s = _s; 44fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman size_t pos = 0; 45c7f6b8c5d40e17bf43fd3a1549d7d89c9da735e1Gabor Greif ssize_t res; 46fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman struct pollfd pfd; 47fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman 48fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman pfd.fd = fd; 49c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif pfd.events = f == read ? POLLIN : POLLOUT; 50c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif while (n > pos) { 51c23b8719ef9d6b1220e854b37d40e9e1c48a82bcGabor Greif res = (f) (fd, s + pos, n - pos); 52fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman switch (res) { 53fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman case -1: 54fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman if (errno == EINTR) 55fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman continue; 56fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman if ((errno == EAGAIN) || (errno == ENOBUFS)) { 57fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman (void)poll(&pfd, 1, -1); 58c3aae25116e66c177579b0b79182b09340b19753Chris Lattner continue; 5925cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands } 6025cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands return 0; 6125cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands case 0: 6225cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands errno = EPIPE; 6325cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands return pos; 6425cf2275ff7de3de3bc0e508abaf457413d74725Duncan Sands default: 65c3aae25116e66c177579b0b79182b09340b19753Chris Lattner pos += (size_t)res; 66c3aae25116e66c177579b0b79182b09340b19753Chris Lattner } 67c3aae25116e66c177579b0b79182b09340b19753Chris Lattner } 68c3aae25116e66c177579b0b79182b09340b19753Chris Lattner return (pos); 69c3aae25116e66c177579b0b79182b09340b19753Chris Lattner} 70c3aae25116e66c177579b0b79182b09340b19753Chris Lattner