mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Rich Felker <dalias@libc.org>
To: musl@lists.openwall.com
Subject: Re: [PATCH v7] stdio: implement fopencookie(3)
Date: Fri, 17 Nov 2017 12:57:01 -0500	[thread overview]
Message-ID: <20171117175701.GE1627@brightrain.aerifal.cx> (raw)
In-Reply-To: <20171117173541.GD1627@brightrain.aerifal.cx>

On Fri, Nov 17, 2017 at 12:35:41PM -0500, Rich Felker wrote:
> On Thu, Nov 16, 2017 at 06:00:55AM +0000, William Pitcock wrote:
> > The fopencookie(3) function allows the programmer to create a custom
> > stdio implementation, using four hook functions which operate on a
> > "cookie" data type.
> >
> > [...]
> > +
> > +struct fcookie {
> > +	void *cookie;
> > +	cookie_io_functions_t iofuncs;
> > +};
> > +
> > +struct cookie_FILE {
> > +	FILE f;
> > +	struct fcookie fc;
> > +	unsigned char buf[UNGET+BUFSIZ];
> > +};
> > +
> > +static size_t cookieread(FILE *f, unsigned char *buf, size_t len)
> > +{
> > +	struct fcookie *fc = f->cookie;
> > +	ssize_t ret = -1;
> > +	size_t remain = len, readlen = 0;
> > +
> > +	if (!fc->iofuncs.read) goto bail;
> > +
> > +	ret = fc->iofuncs.read(fc->cookie, (char *) buf, len > 1 ? (len - 1) : 1);
> > +	if (ret <= 0) goto bail;
> > +
> > +	readlen += ret;
> > +	remain -= ret;
> > +
> > +	f->rpos = f->buf;
> > +	ret = fc->iofuncs.read(fc->cookie, (char *) f->rpos, f->buf_size);
> > +	if (ret <= 0) goto bail;
> > +	f->rend = f->rpos + ret;
> > +
> > +	if (remain > 0) {
> > +		if (remain > f->buf_size) remain = f->buf_size;
> > +		memcpy(buf + readlen, f->rpos, remain);
> > +		readlen += remain;
> > +		f->rpos += remain;
> > +	}
> > +
> > +	return readlen;
> > +
> > +bail:
> > +	f->flags |= F_EOF ^ ((F_ERR^F_EOF) & ret);
> > +	f->rpos = f->rend = f->buf;
> > +	return readlen;
> > +}
> 
> At least the following bugs are still present:
> 
> 1. If len==1, the read func is called twice, and might block the
>    second time even though the requested read of 1 byte succeeded.
> 
> 2. The return value is wrong. It must be between 0 and len and
>    represent the amount of data made available to the caller. Buffer
>    filling is not supposed to be included in that since it's an
>    internal matter, not something the caller sees.
> 
> 3. A return value <=0 from buffer filling step is not cause to set the
>    EOF or error indicators, since the part the caller requested
>    succeeded. But see below...

Also:

4. The return value of the second read call is basically ignored,
   except checking for error/eof. The code just assumes at least
   `f->buf_size` bytes were read successfully, copying junk out of the
   buffer back to the caller if fewer were read.

Rich


  reply	other threads:[~2017-11-17 17:57 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-16  6:00 William Pitcock
2017-11-17 17:35 ` Rich Felker
2017-11-17 17:57   ` Rich Felker [this message]
2017-11-17 19:52   ` William Pitcock

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171117175701.GE1627@brightrain.aerifal.cx \
    --to=dalias@libc.org \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).