/* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ #include #include #include #include #include ssize_t writev (int fd, const struct iovec *iov, int iovcnt) { int old_errno = errno; size_t maxbytes; ssize_t nbytes = 0; ssize_t ret; int i; /* Check args */ if ((iovcnt <= 0) || (iovcnt > IOV_MAX)) { errno = EINVAL; return(-1); } /* Calculate the total number of bytes needed to write data. */ for (maxbytes = 0, i = 0; i < iovcnt; i++) { maxbytes += iov[i].iov_len; if (maxbytes > SSIZE_MAX) break; } /* If we write the maximum number of bytes, we may overflow the return * value. Return an error if this is the case. */ if (maxbytes > SSIZE_MAX) { errno = EINVAL; return(-1); } /* Write out the data vector-by-vector. */ for (i = 0; i < iovcnt; i++) { ret = write(fd, iov[i].iov_base, iov[i].iov_len); if (ret < 0) { if (!i) { /* Fail of the first one. Fail and pass through errno. */ return(-1); } else { /* Hide the error and return what we've written so far. */ errno = old_errno; return(nbytes); } } nbytes += ret; /* If we didn't write out a whole vector, stop. */ if ((size_t) ret < iov[i].iov_len) break; } return(nbytes); }