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
next prev parent 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).