X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=snprintf%2Fpatient_write.c;h=aa59ba1457d92ece99df4ac4daa7acc001d31e12;hb=9fe043d73a3e2112f859ce1fa489021a96efecc9;hp=9bd2913f58ecbed3a9e56f4e6b5481d974f1d9d6;hpb=49705576d8779e3fa2b3efc4294bc03261f76935;p=deliverable%2Flttng-ust.git diff --git a/snprintf/patient_write.c b/snprintf/patient_write.c index 9bd2913f..aa59ba14 100644 --- a/snprintf/patient_write.c +++ b/snprintf/patient_write.c @@ -22,6 +22,9 @@ /* write() */ #include +/* writev() */ +#include + /* send() */ #include #include @@ -58,6 +61,52 @@ ssize_t patient_write(int fd, const void *buf, size_t count) return bufc-(const char *)buf; } +/* + * The `struct iovec *iov` is not `const` because we modify it to support + * partial writes. + */ +ssize_t patient_writev(int fd, struct iovec *iov, int iovcnt) +{ + ssize_t written, total_written = 0; + int curr_element_idx = 0; + + for(;;) { + written = writev(fd, iov + curr_element_idx, + iovcnt - curr_element_idx); + if (written == -1 && errno == EINTR) { + continue; + } + if (written <= 0) { + return written; + } + + total_written += written; + + /* + * If it's not the last element in the vector and we have + * written more than the current element size, then increment + * the current element index until we reach the element that + * was partially written. + */ + while (curr_element_idx < iovcnt && + written >= iov[curr_element_idx].iov_len) { + written -= iov[curr_element_idx].iov_len; + curr_element_idx++; + } + + /* Maybe we are done. */ + if (curr_element_idx >= iovcnt) { + break; + } + + /* Update the current element base and size. */ + iov[curr_element_idx].iov_base += written; + iov[curr_element_idx].iov_len -= written; + } + + return total_written; +} + ssize_t patient_send(int fd, const void *buf, size_t count, int flags) { const char *bufc = (const char *) buf;