#include "internal.h" int io·seek(io·Header *io, intptr offset, int whence, intptr *pos) { intptr n,d,cap; switch(io->state){ default: fmt·fprint(2, "seek: unknown state %d\n", io->state); return io·BufEof; case io·BufEnd: io->state = io·BufRdr; io->ilen = 0; io->g = io->e; /* fallthrough */ case io·BufRdr: n = offset; if(whence == sys·SeekCur){ n += io·offset(io); whence = sys·SeekSet; } /* can we seek inside our buffer */ if(whence == sys·SeekSet){ d = n - io·offset(io); cap = io->e - io->g; if(-cap <= d && d <= cap){ io->ilen += d; if(d >= 0){ if(io->ilen <= 0){ *pos = n; return 0; } }else{ if(io->e - io->g >= -io->ilen){ *pos = n; return 0; } } } } /* nope, call the kernel to do it for us */ sys·seek(io->fd, offset, whence, &n); io->ilen = 0; io->g = io->e; break; case io·BufWtr: io·flush(io); sys·seek(io->fd, offset, whence, &n); break; } io->pos = *pos = n; return 0; }