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