diff mbox series

[v2] Document limitations on streams passed to freopen

Message ID 27db72a2-3467-be3-8f43-1261e586ad5b@redhat.com
State New
Headers show
Series [v2] Document limitations on streams passed to freopen | expand

Commit Message

Joseph Myers Sept. 6, 2024, 7:41 p.m. UTC
On Fri, 6 Sep 2024, Florian Weimer wrote:

> We support reassignment of stdin etc., so please say something like “the
> original values of the standatd streams @code{stdin}”.  Assignment to
> stdin does not magically make freopen valid.

Fixed in this version.


Document limitations on streams passed to freopen

As recently discussed, document that freopen does not work with
streams opened with functions such as popen, fmemopen, open_memstream
or fopencookie.  I've filed
<https://austingroupbugs.net/view.php?id=1855> to clarify this issue
in POSIX.

Tested with "make info" and "make html".

---

Changed in v2: specify that it's the original values of the standard
streams that are supported, rather than some non-fopen-opened stream
that might have been assigned to them.

Comments

Carlos O'Donell Sept. 6, 2024, 8:17 p.m. UTC | #1
On 9/6/24 3:41 PM, Joseph Myers wrote:
> On Fri, 6 Sep 2024, Florian Weimer wrote:
> 
>> We support reassignment of stdin etc., so please say something like “the
>> original values of the standatd streams @code{stdin}”.  Assignment to
>> stdin does not magically make freopen valid.
> 
> Fixed in this version.
> 
> 
> Document limitations on streams passed to freopen
> 
> As recently discussed, document that freopen does not work with
> streams opened with functions such as popen, fmemopen, open_memstream
> or fopencookie.  I've filed
> <https://austingroupbugs.net/view.php?id=1855> to clarify this issue
> in POSIX.
> 
> Tested with "make info" and "make html".

I was looking at his recently in light of Aaron's double-fclose test.

LGTM.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> ---
> 
> Changed in v2: specify that it's the original values of the standard
> streams that are supported, rather than some non-fopen-opened stream
> that might have been assigned to them.
> 
> diff --git a/manual/stdio.texi b/manual/stdio.texi
> index 29888a361f..8590ae955a 100644
> --- a/manual/stdio.texi
> +++ b/manual/stdio.texi
> @@ -330,6 +330,14 @@ this ability, so using @code{freopen} is more portable.
>  When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} on a
>  32 bit machine this function is in fact @code{freopen64} since the LFS
>  interface replaces transparently the old interface.
> +
> +@Theglibc{} only supports use of @code{freopen} on streams opened with
> +@code{fopen} or @code{fopen64} and on the original values of the

OK. You write "original values", but the standard might say "at program startup" as
it does with errno. I interpret them to be the same and I think it is sensible to
interpret "original value" as "at program startup."

> +standard streams @code{stdin}, @code{stdout}, and @code{stderr}; such
> +a stream may be reopened multiple times with @code{freopen}.  If it is
> +called on another kind of stream (opened with functions such as
> +@code{popen}, @code{fmemopen}, @code{open_memstream}, and
> +@code{fopencookie}), @code{freopen} fails and returns a null pointer.
>  @end deftypefun
>  
>  @deftypefun {FILE *} freopen64 (const char *@var{filename}, const char *@var{opentype}, FILE *@var{stream})
>
Maciej W. Rozycki Sept. 9, 2024, 1:51 p.m. UTC | #2
On Fri, 6 Sep 2024, Joseph Myers wrote:

> diff --git a/manual/stdio.texi b/manual/stdio.texi
> index 29888a361f..8590ae955a 100644
> --- a/manual/stdio.texi
> +++ b/manual/stdio.texi
> @@ -330,6 +330,14 @@ this ability, so using @code{freopen} is more portable.
>  When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} on a
>  32 bit machine this function is in fact @code{freopen64} since the LFS
>  interface replaces transparently the old interface.
> +
> +@Theglibc{} only supports use of @code{freopen} on streams opened with
> +@code{fopen} or @code{fopen64} and on the original values of the
> +standard streams @code{stdin}, @code{stdout}, and @code{stderr}; such
> +a stream may be reopened multiple times with @code{freopen}.  If it is
> +called on another kind of stream (opened with functions such as
> +@code{popen}, @code{fmemopen}, @code{open_memstream}, and
> +@code{fopencookie}), @code{freopen} fails and returns a null pointer.
>  @end deftypefun

 Presumably the file associated with the underlying file descriptor will 
have been closed upon return regardless of the failure of the function, 
correct?  Also what about the case where filename requested was a null 
pointer?

  Maciej
Joseph Myers Sept. 9, 2024, 6:03 p.m. UTC | #3
On Mon, 9 Sep 2024, Maciej W. Rozycki wrote:

> On Fri, 6 Sep 2024, Joseph Myers wrote:
> 
> > diff --git a/manual/stdio.texi b/manual/stdio.texi
> > index 29888a361f..8590ae955a 100644
> > --- a/manual/stdio.texi
> > +++ b/manual/stdio.texi
> > @@ -330,6 +330,14 @@ this ability, so using @code{freopen} is more portable.
> >  When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} on a
> >  32 bit machine this function is in fact @code{freopen64} since the LFS
> >  interface replaces transparently the old interface.
> > +
> > +@Theglibc{} only supports use of @code{freopen} on streams opened with
> > +@code{fopen} or @code{fopen64} and on the original values of the
> > +standard streams @code{stdin}, @code{stdout}, and @code{stderr}; such
> > +a stream may be reopened multiple times with @code{freopen}.  If it is
> > +called on another kind of stream (opened with functions such as
> > +@code{popen}, @code{fmemopen}, @code{open_memstream}, and
> > +@code{fopencookie}), @code{freopen} fails and returns a null pointer.
> >  @end deftypefun
> 
>  Presumably the file associated with the underlying file descriptor will 
> have been closed upon return regardless of the failure of the function, 
> correct?  Also what about the case where filename requested was a null 
> pointer?

If the file was opened with fopen (or is the initial value of stdin / 
stdout / stderr), then the file descriptor will have been closed.  The 
other cases mostly don't have an underlying file descriptor, and none of 
these patches relating to freopen change what happens in those cases 
(currently that the stream is flushed but not closed) - the POSIX bug will 
hopefully lead to an answer for whether those other cases should be valid 
(either in the sense of "not undefined behavior but may fail after closing 
the stream" or in the sense of "freopen should actually succeed").
diff mbox series

Patch

diff --git a/manual/stdio.texi b/manual/stdio.texi
index 29888a361f..8590ae955a 100644
--- a/manual/stdio.texi
+++ b/manual/stdio.texi
@@ -330,6 +330,14 @@  this ability, so using @code{freopen} is more portable.
 When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} on a
 32 bit machine this function is in fact @code{freopen64} since the LFS
 interface replaces transparently the old interface.
+
+@Theglibc{} only supports use of @code{freopen} on streams opened with
+@code{fopen} or @code{fopen64} and on the original values of the
+standard streams @code{stdin}, @code{stdout}, and @code{stderr}; such
+a stream may be reopened multiple times with @code{freopen}.  If it is
+called on another kind of stream (opened with functions such as
+@code{popen}, @code{fmemopen}, @code{open_memstream}, and
+@code{fopencookie}), @code{freopen} fails and returns a null pointer.
 @end deftypefun
 
 @deftypefun {FILE *} freopen64 (const char *@var{filename}, const char *@var{opentype}, FILE *@var{stream})