aboutsummaryrefslogtreecommitdiff
path: root/src/base/io/write.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/io/write.c')
-rw-r--r--src/base/io/write.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/src/base/io/write.c b/src/base/io/write.c
index 63df664..2f37200 100644
--- a/src/base/io/write.c
+++ b/src/base/io/write.c
@@ -1,7 +1,40 @@
#include "internal.h"
-int
-io·write(io·Stream *s, int sz, int n, void *buf)
+intptr
+io·write(io·Header *io, intptr len, void *buf)
{
- return fwrite(buf, sz, n, s);
+ char *b;
+ intptr c, o, nw, n;
+
+ b = buf;
+ c = len;
+ o = io->olen;
+
+ while(c > 0){
+ n = -o;
+ if(n > c)
+ n = c;
+ if(n == 0){
+ if(io->state != io·BufWtr)
+ return io·BufEof;
+ switch(sys·write(io->fd, io->cap, io->b, &nw)){
+ case 0:
+ if(nw != io->cap) goto error;
+ io->pos += nw;
+ o = -io->cap;
+ continue;
+ case sys·ErrorInterrupt:
+ io->state = io·BufNil;
+ /* fallthrough */
+ default: error:
+ return io·BufEof;
+ }
+ }
+ mem·move(io->e+o, b, n);
+ o += n;
+ c -= n;
+ b += n;
+ }
+ io->olen = o;
+ return len-c;
}