|
|
|
@ -9,6 +9,12 @@ struct cookie { |
|
|
|
int mode; |
|
|
|
}; |
|
|
|
|
|
|
|
struct mem_FILE { |
|
|
|
FILE f; |
|
|
|
struct cookie c; |
|
|
|
unsigned char buf[UNGET+BUFSIZ], buf2[]; |
|
|
|
}; |
|
|
|
|
|
|
|
static off_t mseek(FILE *f, off_t off, int whence) |
|
|
|
{ |
|
|
|
ssize_t base; |
|
|
|
@ -72,8 +78,7 @@ static int mclose(FILE *m) |
|
|
|
|
|
|
|
FILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode) |
|
|
|
{ |
|
|
|
FILE *f; |
|
|
|
struct cookie *c; |
|
|
|
struct mem_FILE *f; |
|
|
|
int plus = !!strchr(mode, '+'); |
|
|
|
|
|
|
|
if (!size || !strchr("rwa", *mode)) { |
|
|
|
@ -86,29 +91,34 @@ FILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
f = calloc(sizeof *f + sizeof *c + UNGET + BUFSIZ + (buf?0:size), 1); |
|
|
|
f = malloc(sizeof *f + (buf?0:size)); |
|
|
|
if (!f) return 0; |
|
|
|
f->cookie = c = (void *)(f+1); |
|
|
|
f->fd = -1; |
|
|
|
f->lbf = EOF; |
|
|
|
f->buf = (unsigned char *)(c+1) + UNGET; |
|
|
|
f->buf_size = BUFSIZ; |
|
|
|
if (!buf) buf = f->buf + BUFSIZ; |
|
|
|
memset(&f->f, 0, sizeof f->f); |
|
|
|
f->f.cookie = &f->c; |
|
|
|
f->f.fd = -1; |
|
|
|
f->f.lbf = EOF; |
|
|
|
f->f.buf = f->buf + UNGET; |
|
|
|
f->f.buf_size = sizeof f->buf - UNGET; |
|
|
|
if (!buf) { |
|
|
|
buf = f->buf2;; |
|
|
|
memset(buf, 0, size); |
|
|
|
} |
|
|
|
|
|
|
|
c->buf = buf; |
|
|
|
c->size = size; |
|
|
|
c->mode = *mode; |
|
|
|
memset(&f->c, 0, sizeof f->c); |
|
|
|
f->c.buf = buf; |
|
|
|
f->c.size = size; |
|
|
|
f->c.mode = *mode; |
|
|
|
|
|
|
|
if (!plus) f->flags = (*mode == 'r') ? F_NOWR : F_NORD; |
|
|
|
if (*mode == 'r') c->len = size; |
|
|
|
else if (*mode == 'a') c->len = c->pos = strnlen(buf, size); |
|
|
|
if (!plus) f->f.flags = (*mode == 'r') ? F_NOWR : F_NORD; |
|
|
|
if (*mode == 'r') f->c.len = size; |
|
|
|
else if (*mode == 'a') f->c.len = f->c.pos = strnlen(buf, size); |
|
|
|
|
|
|
|
f->read = mread; |
|
|
|
f->write = mwrite; |
|
|
|
f->seek = mseek; |
|
|
|
f->close = mclose; |
|
|
|
f->f.read = mread; |
|
|
|
f->f.write = mwrite; |
|
|
|
f->f.seek = mseek; |
|
|
|
f->f.close = mclose; |
|
|
|
|
|
|
|
if (!libc.threaded) f->lock = -1; |
|
|
|
if (!libc.threaded) f->f.lock = -1; |
|
|
|
|
|
|
|
return __ofl_add(f); |
|
|
|
return __ofl_add(&f->f); |
|
|
|
} |
|
|
|
|