1570af302Sopenharmony_ci#include "stdio_impl.h" 2570af302Sopenharmony_ci#include <sys/uio.h> 3570af302Sopenharmony_ci#include <string.h> 4570af302Sopenharmony_ci 5570af302Sopenharmony_cissize_t __flush_buffer(FILE *f) 6570af302Sopenharmony_ci{ 7570af302Sopenharmony_ci ssize_t cnt = 0; 8570af302Sopenharmony_ci char *wbase = (char *)f->wbase; 9570af302Sopenharmony_ci size_t rem = f->wpos - f->wbase; 10570af302Sopenharmony_ci while (rem > 0) { 11570af302Sopenharmony_ci cnt = syscall(SYS_write, f->fd, wbase, rem); 12570af302Sopenharmony_ci if (cnt < 0) { 13570af302Sopenharmony_ci f->wpos = f->wbase = f->wend = 0; 14570af302Sopenharmony_ci f->flags |= F_ERR; 15570af302Sopenharmony_ci return cnt; 16570af302Sopenharmony_ci } 17570af302Sopenharmony_ci wbase += cnt; 18570af302Sopenharmony_ci rem -= cnt; 19570af302Sopenharmony_ci } 20570af302Sopenharmony_ci 21570af302Sopenharmony_ci /* reset file buffer */ 22570af302Sopenharmony_ci f->wend = f->buf + f->buf_size; 23570af302Sopenharmony_ci f->wpos = f->wbase = f->buf; 24570af302Sopenharmony_ci return cnt; 25570af302Sopenharmony_ci} 26570af302Sopenharmony_ci 27570af302Sopenharmony_cisize_t __stdio_write(FILE *f, const unsigned char *buf, size_t len) 28570af302Sopenharmony_ci{ 29570af302Sopenharmony_ci size_t rem = len; 30570af302Sopenharmony_ci unsigned char *wbuf = (unsigned char *)buf; 31570af302Sopenharmony_ci 32570af302Sopenharmony_ci /* flush buffer first */ 33570af302Sopenharmony_ci ssize_t cnt = __flush_buffer(f); 34570af302Sopenharmony_ci if (cnt < 0) { 35570af302Sopenharmony_ci return 0; 36570af302Sopenharmony_ci } 37570af302Sopenharmony_ci 38570af302Sopenharmony_ci for (;;) { 39570af302Sopenharmony_ci if (f->lbf < 0 && rem <= f->wend - f->wpos) { 40570af302Sopenharmony_ci memcpy(f->wpos, wbuf, rem); 41570af302Sopenharmony_ci f->wpos += rem; 42570af302Sopenharmony_ci return len; 43570af302Sopenharmony_ci } 44570af302Sopenharmony_ci 45570af302Sopenharmony_ci /* write directly if 46570af302Sopenharmony_ci * 1. file buffer < rem 47570af302Sopenharmony_ci * 2. line buffer mode 48570af302Sopenharmony_ci */ 49570af302Sopenharmony_ci cnt = syscall(SYS_write, f->fd, wbuf, rem); 50570af302Sopenharmony_ci if (cnt < 0) { 51570af302Sopenharmony_ci f->wpos = f->wbase = f->wend = 0; 52570af302Sopenharmony_ci f->flags |= F_ERR; 53570af302Sopenharmony_ci return len - rem; 54570af302Sopenharmony_ci } 55570af302Sopenharmony_ci 56570af302Sopenharmony_ci rem -= cnt; 57570af302Sopenharmony_ci wbuf += cnt; 58570af302Sopenharmony_ci if (rem == 0) { 59570af302Sopenharmony_ci break; 60570af302Sopenharmony_ci } 61570af302Sopenharmony_ci } 62570af302Sopenharmony_ci 63570af302Sopenharmony_ci return len; 64570af302Sopenharmony_ci} 65