__stdio_write.c raw

   1  #include "stdio_impl.h"
   2  #include <sys/uio.h>
   3  
   4  size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
   5  {
   6  	struct iovec iovs[2] = {
   7  		{ .iov_base = f->wbase, .iov_len = f->wpos-f->wbase },
   8  		{ .iov_base = (void *)buf, .iov_len = len }
   9  	};
  10  	struct iovec *iov = iovs;
  11  	size_t rem = iov[0].iov_len + iov[1].iov_len;
  12  	int iovcnt = 2;
  13  	ssize_t cnt;
  14  	for (;;) {
  15  		cnt = syscall(SYS_writev, f->fd, iov, iovcnt);
  16  		if (cnt == rem) {
  17  			f->wend = f->buf + f->buf_size;
  18  			f->wpos = f->wbase = f->buf;
  19  			return len;
  20  		}
  21  		if (cnt < 0) {
  22  			f->wpos = f->wbase = f->wend = 0;
  23  			f->flags |= F_ERR;
  24  			return iovcnt == 2 ? 0 : len-iov[0].iov_len;
  25  		}
  26  		rem -= cnt;
  27  		if (cnt > iov[0].iov_len) {
  28  			cnt -= iov[0].iov_len;
  29  			iov++; iovcnt--;
  30  		}
  31  		iov[0].iov_base = (char *)iov[0].iov_base + cnt;
  32  		iov[0].iov_len -= cnt;
  33  	}
  34  }
  35