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.