00001 /* 00002 * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. 00003 * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00017 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00018 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00019 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00020 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00021 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00022 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00024 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00025 */ 00026 00027 #include "includes.h" 00028 RCSID("$OpenBSD: atomicio.c,v 1.13 2005/05/24 17:32:43 avsm Exp $"); 00029 00030 #include "atomicio.h" 00031 00032 /* 00033 * ensure all of data on socket comes through. f==read || f==vwrite 00034 */ 00035 size_t 00036 atomicio(f, fd, _s, n) 00037 ssize_t (*f) (int, void *, size_t); 00038 int fd; 00039 void *_s; 00040 size_t n; 00041 { 00042 char *s = _s; 00043 size_t pos = 0; 00044 ssize_t res; 00045 00046 while (n > pos) { 00047 res = (f) (fd, s + pos, n - pos); 00048 switch (res) { 00049 case -1: 00050 #ifdef EWOULDBLOCK 00051 if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) 00052 #else 00053 if (errno == EINTR || errno == EAGAIN) 00054 #endif 00055 continue; 00056 return 0; 00057 case 0: 00058 errno = EPIPE; 00059 return pos; 00060 default: 00061 pos += (u_int)res; 00062 } 00063 } 00064 return (pos); 00065 }