Austin Group Defect Tracker

Aardvark Mark IV

Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001406 [1003.1(2016/18)/Issue7+TC2] System Interfaces Editorial Clarification Requested 2020-09-28 21:26 2024-06-11 09:08
Reporter djdelorie View Status public  
Assigned To
Priority normal Resolution Accepted As Marked  
Status Closed  
Name DJ Delorie
Organization Red Hat Inc
User Reference
Section open_memstream
Page Number [^]
Line Number n/a
Interp Status ---
Final Accepted Text See Note: 0006489.
Summary 0001406: clarification of SEEK_END when current pointer doesn't match buffer size
Description Consider 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 Action Please 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().
Tags applied_after_i8d3, issue8
Attached Files

- Relationships
related to 0000456Closedajosey 1003.1(2008)/Issue 7 mandate binary mode of fmemopen 

-  Notes
carlos (reporter)
2020-09-29 17:53

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 (manager)
2020-09-29 20:54
edited on: 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 (reporter)
2020-09-29 23:32

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 (manager)
2021-02-11 17:40

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 (reporter)
2021-02-11 18:43

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 (manager)
2023-09-25 16:13

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 => [^]
2020-09-28 21:26 djdelorie Line Number => n/a
2020-09-29 06:22 Florian Weimer Issue Monitored: Florian Weimer
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
2021-02-11 18:43 shware_systems Note Added: 0005235
2021-02-11 18:43 shware_systems Note Deleted: 0005235
2023-09-25 16:13 Don Cragun Note Added: 0006489
2023-09-25 16:15 Don Cragun Final Accepted Text => See Note: 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

Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker