diff options
| author | Rich Felker <dalias@aerifal.cx> | 2011-03-14 11:49:55 -0400 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2011-03-14 11:49:55 -0400 | 
| commit | 9dd7d7e3f6a90ae00e83fd98f30c48389c4f5ab2 (patch) | |
| tree | a641744df0827b6abe8bd072b1f0c197ac47e3f0 /src/stdio | |
| parent | b446c55b6f2c692c58f32e5777a8976534a03274 (diff) | |
| download | musl-9dd7d7e3f6a90ae00e83fd98f30c48389c4f5ab2.tar.gz | |
partially-written draft of fmemopen, still in #if 0
Diffstat (limited to 'src/stdio')
| -rw-r--r-- | src/stdio/fmemopen.c | 51 | 
1 files changed, 48 insertions, 3 deletions
| diff --git a/src/stdio/fmemopen.c b/src/stdio/fmemopen.c index 77a60746..cc72a420 100644 --- a/src/stdio/fmemopen.c +++ b/src/stdio/fmemopen.c @@ -3,14 +3,59 @@  static ssize_t mread(FILE *f, unsigned char *buf, size_t len)  { -	memcpy(buf,  +	size_t rem = f->memsize - f->mempos; +	if (len > rem) len = rem; +	memcpy(buf, f->membuf+f->mempos, len); +	f->mempos += len; +	return len; +} + +static ssize_t mwrite(FILE *f, const unsigned char *buf, size_t len) +{ +	size_t rem; +	if (f->memmode == 'a') f->mempos = f->memsize; +	rem = f->memlim - f->mempos; +	if (len > rem) len = rem; +	memcpy(f->membuf+f->mempos, buf, len); +	f->mempos += len; +	if (f->mempos >= f->memsize) { +		f->memsize = f->mempos; +	} +	return len;  }  FILE *fmemopen(void *buf, size_t size, const char *mode)  { -	FILE *f = calloc(sizeof(FILE), 1); +	FILE *f; +	int plus = !!strchr(mode, '+'); +	 +	if (!size || !strchr("rwa", *mode)) { +		errno = EINVAL; +		return 0; +	} + +	if (!buf && size > SIZE_MAX-sizeof(FILE)-BUFSIZ-UNGET) { +		errno = ENOMEM; +		return 0; +	} + +	f = calloc(sizeof(FILE) + UNGET + BUFSIZ + (buf?0:size), 1);  	if (!f) return 0; +	f->fd = -1; +	f->lbf = EOF; +	f->buf = (unsigned char *)(f+1) + UNGET; +	f->buf_size = BUFSIZ; +	if (!buf) buf = f->buf + BUFSIZ; -	// +	if (!plus) f->flags = (*mode == 'r') ? F_NOWR : F_NORD; +	if (*mode == 'a') f->mempos = strchr(buf, 0)-buf; + +	f->read = mread; +	f->write = mwrite; +	f->seek = mseek; +	f->flush = mflush; +	f->close = mclose; + +	return f;  }  #endif | 
