1 # STDIO/FWRITE.D - output
3 # (c)Copyright 2020-2021, Matthew Dillon, All Rights Reserved.
4 # See the COPYRIGHT file at the base of the Rune distribution.
8 File.fwrite(void *buf, usize_t bytes)
12 # If a regular file requires a flush prior to turn-around to
13 # ensure that any read-back sees the write.
15 if (this->flags & F_ISREG) {
16 if ((this->flags & F_OUT) == 0) {
24 * If unbuffered just write the data directly
25 * (we are guarenteed to be flushed and it doesn't
26 * matter if we are in input mode).
28 while (this->mode == File.M_NONE) {
29 ssize_t n = this->efd.write1(buf, bytes);
31 if (n < 0 && this->efd.error == Sys.EINTR)
33 return r; # early return
35 buf = (string_rw_p)buf + n;
38 this->pos += (off_t)n;
42 * If we need an output buffer create one
44 if (this->out.buf == NULL) {
49 * Copy to the buffer until the buffer is full
52 usize_t n = this->out.size - this->out.index;
55 if (this->fflush() < 0)
61 Sys.bcopy((string_rw_p)buf + r, &this->out.buf[this->out.index], n);
64 this->pos += (off_t)n;
65 this->out.index += (usize_t)n;
71 if (this->mode == File.M_LINE &&
72 this->out.index != 0L &&
73 this->out.buf[this->out.index - 1L] == '\n'
77 if ((r2 = this->fflush()) < 0)
87 if (this->mode == File.M_NONE) {
88 if (this->efd.write(&c, 1) == 1L) {
96 * If we need an output buffer create one
98 if (this->out.buf == NULL)
102 * Copy data to buffer
104 if (this->out.index == this->out.size) {
105 if (this->fflush() < 0)
108 this->out.buf[this->out.index] = c;
115 if (this->mode == File.M_LINE && c == '\n')
116 return(this->fflush());
127 if (this->out.index != 0L) {
128 while (r != this->out.index) {
131 n = this->efd.write(&this->out.buf[0] + r,
132 this->out.index - r);
137 if (r != 0L && r != this->out.index) {
138 Sys.bcopy(&this->out.buf[r], &this->out.buf[0], this->out.index - r);
140 this->out.index -= r;