diff options
author | Nicholas <nbnoll@eml.cc> | 2021-11-20 20:12:21 -0800 |
---|---|---|
committer | Nicholas <nbnoll@eml.cc> | 2021-11-20 20:12:21 -0800 |
commit | 138fb272fae79587de3469493b55e4d18eadc722 (patch) | |
tree | 447d2af80b8c2ea080253e76d33e128c9b27d3f6 /src/base/bufio/init.c | |
parent | c9a32c1a43d2bdded07eaa45732c3a6e195a5442 (diff) |
Feat: added buffered io from plan9
As we no longer have the FILE type, we need to buffer our reading and
writing so that we don't have to make so many syscalls. The API is nice
so that we can buffer other readers. We will update it so that it eats
io·Readers/io·Writers.
Diffstat (limited to 'src/base/bufio/init.c')
-rw-r--r-- | src/base/bufio/init.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/base/bufio/init.c b/src/base/bufio/init.c new file mode 100644 index 0000000..7e6dcee --- /dev/null +++ b/src/base/bufio/init.c @@ -0,0 +1,102 @@ +#include "internal.h" + +#define MAXHEADERS 20 +static io·Header *tracked[MAXHEADERS]; +static int doexit; + +static void +untrackall(void *arg) +{ + int i; + io·Header *it; + + for(i=0; i < MAXHEADERS; i++){ + it = tracked[i]; + if(it){ + tracked[i] = nil; + bio·flush(it); + } + } +} + +static void +untrack(io·Header *io) +{ + int i; + + for(i=0; i<arrlen(tracked); i++){ + if(tracked[i] == io) + tracked[i] = nil; + } +} + +static void +track(io·Header *io) +{ + int i; + + untrack(io); + for(i=0; i<arrlen(tracked); i++){ + if(!tracked[i]){ + tracked[i] = io; + break; + } + } + + if(!doexit){ + doexit = 1; + rt·atexit(untrackall, nil); + } +} + +int +bio·initcap(io·Header *io, int fd, int mode, int cap, uchar *buf) +{ + buf += io·BufUngets; + cap += io·BufUngets; + + switch(mode & ~(sys·OCloseExec|sys·OTrunc)){ + default: + fmt·fprint(2, "initcap: unknown mode %d\n" , mode); + return io·BufErr; + case sys·ORead: + io->state = io·BufRdr; + io->olen = 0; + break; + case sys·OWrite: + track(io); + io->state = io·BufWtr; + io->olen = -cap; + break; + } + + io->b = buf; + io->e = buf+cap; + io->g = io->e; + io->fd = fd; + io->cap = cap; + io->pos = io->runesz = io->flag = io->ilen = io->line = 0; + return 0; +} + +int +bio·init(io·Buffer *io, int fd, int mode) +{ + return bio·initcap(header(io), fd, mode, io·BufLen + io·BufUngets, io->b); +} + +int +bio·close(io·Header *io) +{ + int err; + + untrack(io); + + err = bio·flush(io); + if(io->flag == io·BufMagic){ + io->flag = 0; + if((err=sys·close(io->fd))) + return err; + } + return 0; +} |