On Sat, Jun 10, 2023 at 11:21:20AM +0200, Claudio Jeker wrote:
> On Sat, Jun 10, 2023 at 10:15:53AM +0200, Theo Buehler wrote:
> > On Sat, Jun 10, 2023 at 09:00:54AM +0200, Claudio Jeker wrote:
> > > Instead of building an API for ibufs to handle dynamic strings use
> > > open_memstream(3) which does the same via stdio.
> > >
> > > Now open_memstream() requires a bit more plumbing (one needs to close the
> > > FILE stream and free the buffer) but on the plus side you can use all
> > > stdio functions like fprintf() to fill this string.
> > > While doing this also add error handling and check if the generated string
> > > was created successfully before calling log_info().
> >
> > This is a lot better than the mess that was there before. One thing I'm
> > not entirely sure about is whether fflush() can fail. I think it can't
> > since previous writes should already have led to reallocations, so
> > another ferror() after fflush() would probably be overdoing it.
>
> Indeed, I was under the impression that fflush() would just update the
> pointers but actually the fflush() call is needed to flush out the
> internal stdio buffer into the open_memstream() buffer.
I see, I missed that. Agreed.
> So the fflush()
> should happen before checking for errors. Another option is to use
> setvbuf() with _IONBF to make the FILE stream unbuffered.
I'd rather avoid further complexity.
> So the new pattern is:
> fflush(spif);
> if (ftello(spif) > 0 && !ferror(spif)) {
> log_info(...
Our ftello() calls __sflush() internally, so at least for OpenBSD the
original fflush() call should not be able to fail (and is redundant in
either version). I'm not sure we can rely on that in portable, so I think
your new pattern is the right thing to do.