ptg10805159
Appendix C Chapter 5 Solutions 917
if (ms->curpos > ms->vsize) {
ms->vsize = ms->curpos;
if (((ms->flags & (MS_READ|MS_WRITE)) ==
(MS_READ|MS_WRITE)) && (ms->vsize < ms->rsize))
*(ms->buf + ms->vsize) = 0;
}
if ((ms->flags & (MS_WRITE|MS_APPEND)) &&
!(ms->flags & MS_READ)) {
if (ms->curpos < ms->rsize)
*(ms->buf + ms->curpos) = 0;
else
*(ms->buf + ms->rsize - 1) = 0;
}
return(nw);
}
static fpos_t
mstream_seek(void *cookie, fpos_t pos, int whence)
{
int off;
struct memstream *ms = cookie;
switch (whence) {
case SEEK_SET:
off = pos;
break;
case SEEK_END:
off = ms->vsize + pos;
break;
case SEEK_CUR:
off = ms->curpos + pos;
break;
}
if (off < 0 || off > ms->vsize) {
errno = EINVAL;
return -1;
}
ms->curpos = off;
return(off);
}
static int
mstream_close(void *cookie)
{
struct memstream *ms = cookie;
if (ms->flags & MS_MYBUF)
free(ms->buf);
free(ms);
return(0);
}
Figure C.4 Implementation offmemopenfor BSD systems