View Issue Details

IDProjectCategoryView StatusLast Update
00018551003.1(2024)/Issue8System Interfacespublic2024-11-07 16:39
Reporterjsm28 Assigned To 
PrioritynormalSeverityCommentTypeClarification Requested
Status Interpretation RequiredResolutionAccepted As Marked 
NameJoseph Myers
Organization
User Reference
Sectionfreopen
Page Number1030-1034
Line Number35272-35445
Interp StatusApproved
Final Accepted Text0001855:0006893
Summary0001855: Use of freopen with different kinds of streams
DescriptionWhen is it valid to use freopen with a stream that did not originate from fopen and is not one of stdin, stdout or stderr?

* Is it valid to use freopen on a stream originating with popen? I think it's understood that streams opened with popen are to be closed with pclose - but the popen normative text doesn't say that (only the APPLICATION USAGE says they "should" be closed with pclose) and I don't see anything in either the fclose or freopen normative text to disallow use of those functions on such a stream either.

* What about streams originating with fmemopen or open_memstream? Can freopen be used on those streams? And does that depend on whether the pathname argument to freopen is a null pointer - does the EBADF error for "The file descriptor underlying the stream is not a valid file descriptor when pathname is a null pointer." require freopen with pathname == NULL to fail for streams from fmemopen or open_memstream because there is no underlying file descriptor for such streams?
Desired ActionClarify what combinations of opening / reopening / closing functions are valid on streams - both "valid" as in "does not result in undefined behavior", and "valid" as in "required to work with specific semantics or produce one of the specified errors if the relevant conditions are met".
Tagstc1-2024

Relationships

related to 0001880 Resolved Missing CX shading on text about file descriptors 

Activities

geoffclare

2024-09-26 16:12

manager   bugnote:0006893

Interpretation response
------------------------

Regarding the use of freopen() with a non-null pathname, the standard clearly states that freopen() first attempts to flush the stream then closes any file descriptor associated with the stream, and conforming implementations must conform to this.

Regarding the use of freopen() with a null pathname on a stream that has an associated file descriptor, the standard clearly states that the file descriptor associated with the stream need not be closed if the call to freopen() succeeds and that it is implementation-defined which changes of mode are permitted (if any), and under what circumstances, and conforming implementations must conform to this.

Regarding the use of freopen() with a null pathname on a stream that does not have an associated file descriptor, the standard is unclear on this issue, and no conformance distinction can be made between alternative implementations based on this. This is being referred to the sponsor.

Rationale:
-------------
There are unusual but valid use cases where a stream opened with popen() would not be closed with pclose(), such as forking after popen() and using fclose() or freopen() on the stream in the child. Another use case would be if an application wants to be able to detect that the child started by popen() was stopped by a signal. It would need to find out the process ID by some means (e.g. read it from the stream) but it could then call waitpid() and either fclose() or freopen() instead of using pclose().

On memory streams, with a non-null pathname the standard uses "if any" in the stated requirement about an associated file descriptor. However, with a null pathname there are references to the associated file descriptor which assume there is one.

Notes to the Editor (not part of this interpretation):
-------------------------------------------------------

On page 1030 line 35294 section freopen(), change:
In this case, the file descriptor associated with the stream need not be closed if the call to freopen() succeeds.

to:
In this case, if there is a file descriptor associated with the stream, it need not be closed if the call to freopen() succeeds.


On page 1030 line 35313 section freopen(), change:
The file descriptor underlying the stream is not a valid file descriptor when pathname is a null pointer.

to:
The file descriptor associated with the stream, if any, is not a valid file descriptor when pathname is a null pointer.


On page 1031 line 35351 section freopen(), change:
The mode with which the file descriptor underlying the stream was opened does not support the requested mode when pathname is a null pointer.

to:
The mode with which the file descriptor associated with the stream, if any, was opened does not support the requested mode when pathname is a null pointer.

    
After page 1032 line 35390 section freopen(), add a paragraph to APPLICATION USAGE:
The use of freopen() on streams opened with open_memstream() or open_wmemstream() is discouraged, as some of the requirements stated in the description of those functions are conditional on there having been a successful fflush() or fclose() on the stream. These cannot be relied upon if freopen() is used (without first doing an explicit fflush()) because freopen() ignores failure of the flush operation.

agadmin

2024-09-27 08:43

administrator   bugnote:0006894

Interpretation proposed: 27 September 2024

gbrandenrobinson

2024-10-10 16:00

reporter   bugnote:0006910

Re: note 6893:

Speaking as a lay person only glancingly familiar with standardese:

"Regarding the use of freopen() with a null pathname on a stream that has an associated file descriptor, the standard clearly states that the file descriptor associated with the stream need not be closed if the call to freopen() succeeds and that it is implementation-defined which changes of mode are permitted (if any), and under what circumstances, and conforming implementations must conform to this."

I find that paragraph hard to interpret. I infer two stipulations:

1. the file descriptor associated with the stream NEED NOT be closed if freopen() succeeds; and
2. changes of mode under such a circumstance are completely at the discretion of the implementation.

When I try to deduce what behavior "must be" conformed with thus, I am at a loss. You can close the descriptor, or not, and you will be conformant. You can change some, none, or all file modes, and you will be conformant.

It seems like there is no requirement to conform to here.

Can someone illuminate the matter?

geoffclare

2024-10-10 16:31

manager   bugnote:0006911

> It seems like there is no requirement to conform to here.

When behaviour is "implementation-defined", the implementation is required to document the behaviour.

agadmin

2024-11-07 16:39

administrator   bugnote:0006950

Interpretation approved: 7th November 2024

Issue History

Date Modified Username Field Change
2024-09-05 21:36 jsm28 New Issue
2024-09-05 21:36 jsm28 Name => Joseph Myers
2024-09-05 21:36 jsm28 Section => freopen
2024-09-05 21:36 jsm28 Page Number => 1030-1034
2024-09-05 21:36 jsm28 Line Number => 35272-35445
2024-09-26 16:12 geoffclare Note Added: 0006893
2024-09-26 16:14 geoffclare Interp Status => Pending
2024-09-26 16:14 geoffclare Final Accepted Text => 0001855:0006893
2024-09-26 16:14 geoffclare Status New => Interpretation Required
2024-09-26 16:14 geoffclare Resolution Open => Accepted As Marked
2024-09-26 16:14 geoffclare Tag Attached: tc1-2024
2024-09-27 08:43 agadmin Interp Status Pending => Proposed
2024-09-27 08:43 agadmin Note Added: 0006894
2024-10-10 16:00 gbrandenrobinson Note Added: 0006910
2024-10-10 16:31 geoffclare Note Added: 0006911
2024-11-07 16:39 agadmin Interp Status Proposed => Approved
2024-11-07 16:39 agadmin Note Added: 0006950
2024-11-28 15:12 geoffclare Relationship added related to 0001880