diff options
Diffstat (limited to 'tools/blktap2/drivers/atomicio.c')
| -rw-r--r-- | tools/blktap2/drivers/atomicio.c | 61 | 
1 files changed, 61 insertions, 0 deletions
diff --git a/tools/blktap2/drivers/atomicio.c b/tools/blktap2/drivers/atomicio.c new file mode 100644 index 0000000000..ae0e24b00a --- /dev/null +++ b/tools/blktap2/drivers/atomicio.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. + * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <errno.h> +#include "atomicio.h" + +/* + * ensure all of data on socket comes through. f==read || f==vwrite + */ +size_t +atomicio(f, fd, _s, n) +	ssize_t (*f) (int, void *, size_t); +	int fd; +	void *_s; +	size_t n; +{ +	char *s = _s; +	size_t pos = 0; +	ssize_t res; + +	while (n > pos) { +		res = (f) (fd, s + pos, n - pos); +		switch (res) { +		case -1: +			if (errno == EINTR || errno == EAGAIN) +				continue; +			return 0; +		case 0: +			errno = EPIPE; +			return pos; +		default: +			pos += (size_t)res; +		} +	} +	return (pos); +} +  | 
