View Issue Details

IDProjectCategoryView StatusLast Update
00014061003.1(2016/18)/Issue7+TC2System Interfacespublic2024-06-11 09:08
Reporterdjdelorie Assigned To 
PrioritynormalSeverityEditorialTypeClarification Requested
Status ClosedResolutionAccepted As Marked 
NameDJ Delorie
OrganizationRed Hat Inc
User Reference
Sectionopen_memstream
Page Numberhttps://pubs.opengroup.org/onlinepubs/9699919799/functions/open_memstream.html
Line Numbern/a
Interp Status---
Final Accepted TextSee 0001406:0006489.
Summary0001406: clarification of SEEK_END when current pointer doesn't match buffer size
DescriptionConsider a stream created by open_memstream(), where 16 bytes are written, fseek(0,SEEK_POS) to rewind, then write 4 bytes, and fflush(). At this point, the value pointed to by the sizep argument to open_memstream() should be 4 (please confirm).
At this point in the state of the stream, what are the semantics of SEEK_END? What will be the "file size" if you fclose() at this point?
The example explicitly SEEK_SETs to the buffer size before fclose(), eliding the issue.
Desired ActionPlease clarify if SEEK_END is relative to the current position or the current buffer length, and if it's changed by a call to fflush() at that time.
Please clarify if a SEEK_SET to set the current pointer less than the current buffer size, itself (without read/write), changes the SEEK_END semantics, or the value stored in *sizep after fflush().
Tagsapplied_after_i8d3, issue8

Relationships

related to 0000456 Closedajosey 1003.1(2008)/Issue 7 mandate binary mode of fmemopen 
related to 0001858 Interpretation Required 1003.1(2024)/Issue8 open_memstream() doesn't say where the result lies 

Activities

carlos

2020-09-29 17:53

reporter   bugnote:0005011

This isn't an idle request, we are actively trying to harmonize the behaviour of implementations, particularly glibc, musl and FreeBSD to name three. The current wording upstream seems underspecified. At least one Red Hat customer has argued that it should match the behaviour of a normal file-backed stream to avoid confusion. It is clear to me that the intent of open_memstream was *not* to follow the behaviour of file-backed streams because of the special language and programming models that would use the API. Thus this request for guidance and clarification.

Don Cragun

2020-09-29 20:54

manager   bugnote:0005012

Last edited: 2020-09-29 20:55

This bug has been moved from "Base Definitions and Headers" to "System Interfaces".

Noting that the rationale for open_memstream() refers to fmemopen(), I assume that the description of what happens when you use one of the fseek() or fseeko() functions on a memory stream are as described in fmemopen(). Note that in the upcoming revision ot the standard, part of the description of this behavior is changed by the resolution of 0000456.

But, the first paragraph of the description of open_memstream() only says that the stream is opened for writing. It doesn't specify whether it is supposed to use byte mode or text mode (and I believe the mode affects whether of not a NUL byte is written and writing that NUL byte determines whether or not the stream size changes).

djdelorie

2020-09-29 23:32

reporter   bugnote:0005013

The reference to fmemopen() is noted, but as open_memstream() returns the *current* pointer in *sizep in the example, it clouds the issue of what the "end" of the data is - the API does not give the caller a way to determine the current buffer length if the current pointer is not coincident with it, and the NUL terminator is not specified, so having the "end of file" be somewhere undiscoverable seems problematic.
The example given by the standard explicltly uses ftell/fseek to position the current pointer at the "expected" end of data, implying that that would not otherwise be EOF had this not happened.
It is these differences in spec between open_memstream() and fmemopen() that confuse us, hence our request for clarification.

rhansen

2021-02-11 17:40

manager   bugnote:0005233

This was discussed during today's telecon. If I understand correctly, the wording of open_memstream() was originally intended to match glibc's implementation, but it looks like we (the Austin Group) were not successful in crafting wording that unambiguously matches glibc's behavior. We are not very familiar with the various important use cases for this function, so we are not sure what the behavior should be. So, before we can resolve this bug, we need input from the implementors: What do you want the behavior to be?

shware_systems

2021-02-11 18:43

reporter   bugnote:0005234

It looks to me the intent was that the interface shall track SEEK_END as the size of the buffer, ignoring the appended NUL byte. In the example code, the second seeko() should be equivalent to seeko(stream, 0, SEEK_END).

The wording appears to be as it is for the use case when an application does an initial write, then does a large single realloc() of the buffer in expectation of many more writes not needing to do a realloc per write. In this case an arbitrary seek past SEEK_END is permitted, but should not be reflected in len as current or final position on an immediately following flush or close respectively because nothing has been stored yet. The lesser SEEK_END value is the maximum known length so that gets stored. The parameter name probably should be sizeorposp to better reflect this, not sizep, but I don't see a rewind and rewrite affecting SEEK_END, only writes past the current SEEK_END.

Don Cragun

2023-09-25 16:13

manager   bugnote:0006489

New text that allows both behaviours, as an Issue 8 compromise:
Add a new paragraph after issue8 draft 3 P1617. L50906 (in open_memstream())
The fseek() and fseeko() functions can be used to set the file position beyond the current buffer length. It is implementation-defined whether this extends the buffer to the new length. If it extends the buffer, the added buffer contents shall be set to null bytes for open_memstream(), or null wide characters for open_wmemstream(); if it does not extend the buffer, then if data is later written at this point, the buffer contents in the gap shall be set to null bytes for open_memstream(), or null wide characters for open_wmemstream(). If fseek() or fseeko() is called with SEEK_END as the whence argument, it is implementation-defined whether the file position shall be adjusted either relative to the current buffer length or relative to the buffer size that would be set by an fflush() call made immediately before the fseek() or fseeko() call.

Issue History

Date Modified Username Field Change
2020-09-28 21:26 djdelorie New Issue
2020-09-28 21:26 djdelorie Name => DJ Delorie
2020-09-28 21:26 djdelorie Organization => Red Hat Inc
2020-09-28 21:26 djdelorie Section => open_memstream
2020-09-28 21:26 djdelorie Page Number => https://pubs.opengroup.org/onlinepubs/9699919799/functions/open_memstream.html
2020-09-28 21:26 djdelorie Line Number => n/a
2020-09-29 17:53 carlos Note Added: 0005011
2020-09-29 20:54 Don Cragun Interp Status => ---
2020-09-29 20:54 Don Cragun Note Added: 0005012
2020-09-29 20:54 Don Cragun Category Base Definitions and Headers => System Interfaces
2020-09-29 20:55 Don Cragun Note Edited: 0005012
2020-09-29 20:55 Don Cragun Relationship added related to 0000456
2020-09-29 23:32 djdelorie Note Added: 0005013
2021-02-11 17:40 rhansen Note Added: 0005233
2021-02-11 18:43 shware_systems Note Added: 0005234
2023-09-25 16:13 Don Cragun Note Added: 0006489
2023-09-25 16:15 Don Cragun Final Accepted Text => See 0001406:0006489.
2023-09-25 16:15 Don Cragun Status New => Resolved
2023-09-25 16:15 Don Cragun Resolution Open => Accepted As Marked
2023-09-25 16:17 Don Cragun Tag Attached: issue8
2023-10-10 09:16 geoffclare Status Resolved => Applied
2023-10-10 09:16 geoffclare Tag Attached: applied_after_i8d3
2024-06-11 09:08 agadmin Status Applied => Closed
2024-09-26 13:45 geoffclare Relationship added related to 0001858