diff options
| author | Rich Felker <dalias@aerifal.cx> | 2018-04-18 14:57:10 -0400 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2018-04-18 14:58:57 -0400 | 
| commit | 0b043c7b70b204c43dc7dbdb50b12aa8fa7981e8 (patch) | |
| tree | cb094aec35a57a87f6483f436c38ea064ad067ca | |
| parent | 4245a233c147e18a841bc6ccd5aafb65d6bca163 (diff) | |
| download | musl-0b043c7b70b204c43dc7dbdb50b12aa8fa7981e8.tar.gz | |
clean up allocation/setup logic for fmemopen
rather than manually performing pointer arithmetic to carve multiple
objects out of one allocation, use a containing struct that
encompasses them all.
| -rw-r--r-- | src/stdio/fmemopen.c | 52 | 
1 files changed, 31 insertions, 21 deletions
diff --git a/src/stdio/fmemopen.c b/src/stdio/fmemopen.c index 2ce43d32..fb2656e3 100644 --- a/src/stdio/fmemopen.c +++ b/src/stdio/fmemopen.c @@ -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);  }  | 
