/* retry.c -- keep trying write system calls * $Id: retry.c,v 1.22 2003/12/29 21:25:42 rjs3 Exp $ * * Copyright (c) 1998-2003 Carnegie Mellon University. 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. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * */ #include <config.h> #include <errno.h> #include <sys/types.h> #include <sys/uio.h> #ifdef HAVE_UNISTD_H #include <unistd.h> #endif #include "retry.h" /* * Keep calling the read() system call with 'fd', 'buf', and 'nbyte' * until all the data is read in or an error occurs. */ int retry_read(int fd, char *buf, size_t nbyte) { int n; int nread = 0; if (nbyte == 0) return 0; for (;;) { n = read(fd, buf, nbyte); if (n == 0) { /* end of file */ return -1; } if (n == -1) { if (errno == EINTR || errno == EAGAIN) continue; return -1; } nread += n; if (((size_t) n) >= nbyte) return nread; buf += n; nbyte -= n; } } /* * Keep calling the write() system call with 'fd', 'buf', and 'nbyte' * until all the data is written out or an error occurs. */ int retry_write(int fd, const char *buf, size_t nbyte) { int n; int written = 0; if (nbyte == 0) return 0; for (;;) { n = write(fd, buf, nbyte); if (n == -1) { if (errno == EINTR) continue; return -1; } written += n; if (((size_t) n) >= nbyte) return written; buf += n; nbyte -= n; } } /* * Keep calling the writev() system call with 'fd', 'iov', and 'iovcnt' * until all the data is written out or an error occurs. */ int retry_writev(fd, iov, iovcnt) int fd; struct iovec *iov; int iovcnt; { int n; int i; int written = 0; static int iov_max = #ifdef MAXIOV MAXIOV #else #ifdef IOV_MAX IOV_MAX #else 8192 #endif #endif ; for (;;) { while (iovcnt && iov[0].iov_len == 0) { iov++; iovcnt--; } if (!iovcnt) return written; n = writev(fd, iov, iovcnt > iov_max ? iov_max : iovcnt); if (n == -1) { if (errno == EINVAL && iov_max > 10) { iov_max /= 2; continue; } if (errno == EINTR) continue; return -1; } written += n; for (i = 0; i < iovcnt; i++) { if (iov[i].iov_len > (size_t) n) { iov[i].iov_base = (char *)iov[i].iov_base + n; iov[i].iov_len -= n; break; } n -= iov[i].iov_len; iov[i].iov_len = 0; } if (i == iovcnt) return written; } }