[PATCH v2] libio: Fix fmemopen_write on appending condition

Rocket Ma marocketbd@gmail.com
Thu Mar 26 17:10:50 GMT 2026


Adhemerval Zanella Netto <adhemerval.zanella@linaro.org> 于2026年3月26日周四 20:21写道:
> > I know what you mean, but I think this patch should be simple enough to fix only
> > one issue, we could discuss another patch to test other modes to fix Bug 34006.
>
> The problem with this patch it although it fixes the fmemopen result it
> adds another inconsistent with fflush/fclose.  And I don't think we should
> partially fix, the glibc current behavior might not be following POSIX
> but it is still consistent wrt error reporting.

Okay, then we should talk more details on how to fix this problem properly.

> > I tested it in https://sourceware.org/bugzilla/show_bug.cgi?id=34006#c1
> > I think we could fix it in another patch to leave this patch clean and neat.
>
> I don't agree, fflush/fclose will keep returning an error but now the input
> buffer is also modified. This is unexpected and inconsistent.
>
> If the buffer is not correctly modified we need also to proper signal the
> operation to the caller.
>
> > I do think we should advance s=4 instead of 3 according to POSIX.1-2024.
> > Or I misunderstand?
>
> My understanding from fmemopen POSIX description is:
>
>   "[...] A write operation on the stream shall *not* advance the current
>    buffer end position beyond the size given in the max_size argument. [...]"
>
> And I would consider the less expected behavior fwrite to actually return
> the number of bytes it can actually write, instead of relying on fflush/fclose
> to truncate the buffer.

In POSIX note: Note that buf will not be null terminated if max_size bytes are
written to the memory stream. Applications wanting to guarantee that the buffer
will be null terminated need to call fmemopen() with max_size set to one byte
smaller than the actual size of buf and set buf[max_size] to a null byte.

So I think the sentence you mention means `assert (pos <= max_size)`,
i.e., fwrite may writes at maximum of `max_size` bytes, and
`buf[max_size] = '\0'`.

I don't think your patch, adding a specific size of allocated buffer
function, could
work properly. What if the user setbuf manually? That may introduce inconsistent
behavior back again.

In my opinion, since we are manipulating memory, not interacting with kernel,
we should directly set buf to NULL, so fwrite could pass write request to
fmemopen_write directly, and it won't hurt much performance. We just reject
any setbuf requests with errno, for example, EINVAL. If we do this,
fflush/fclose
will never fail, and user will know immediately if the space is not
enough to write,
it will never confuse user.

> > I don't think glibc should fail fast on fwrite. I mounted a tmpfs with 4k size,
> > then write to it with buffered IO, each time 0x1000 and then flush,
> > here is the result:
> >
> > fwrite 0x1000 = 0x1000
> > fflush = 0
> > fwrite 0x1000 = 0x1000
> > fclose = 0xffffffffffffffff No space left on device
> >
> > The source is attached below. In this case, since filesystem FILE
> > behave like this,
> > then why should we fail directly on fwrite?
>
> Well, the rationale of fmemopen addition was to
>
>   "eliminate many of the errors encountered in the construction of strings"
>
> So I am not sure if we apply the same ideas of FILE access, specially because
> silent string truncation is still a source of issue.
>
> At least FreeBSD does return the remaining bytes on fwrite operations (and
> I assume other BSD as well).

Following your rationale, the solution mentioned above may be better.
What do you think?


More information about the Libc-alpha mailing list