Clear flags2 flags set from mode in freopen (bug 32134)

As reported in bug 32134, freopen does not clear the flags set in
fp->_flags2 by the "e", "m" or "c" mode characters.  Clear these so
that they can be set or not as appropriate from the mode string passed
to freopen.  The relevant test for "e" in tst-freopen2-main.c is
enabled accordingly; "c" is expected to be covered in a separately
written test (and while tst-freopen2-main.c does include transitions
to and from "m", that's not really a semantic flag intended to result
in behaving in an observably different way).

Tested for x86_64.
This commit is contained in:
Joseph Myers 2024-09-05 11:15:29 +00:00
parent f169509ded
commit f512634dde
3 changed files with 9 additions and 2 deletions

View File

@ -63,6 +63,9 @@ freopen (const char *filename, const char *mode, FILE *fp)
up here. */
_IO_old_file_close_it (fp);
_IO_JUMPS_FUNC_UPDATE (fp, &_IO_old_file_jumps);
fp->_flags2 &= ~(_IO_FLAGS2_MMAP
| _IO_FLAGS2_NOTCANCEL
| _IO_FLAGS2_CLOEXEC);
result = _IO_old_file_fopen (fp, gfilename, mode);
}
else
@ -72,6 +75,9 @@ freopen (const char *filename, const char *mode, FILE *fp)
_IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
fp->_flags2 &= ~(_IO_FLAGS2_MMAP
| _IO_FLAGS2_NOTCANCEL
| _IO_FLAGS2_CLOEXEC);
result = _IO_file_fopen (fp, gfilename, mode, 1);
if (result != NULL)
result = __fopen_maybe_mmap (result);

View File

@ -56,6 +56,9 @@ freopen64 (const char *filename, const char *mode, FILE *fp)
_IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
fp->_flags2 &= ~(_IO_FLAGS2_MMAP
| _IO_FLAGS2_NOTCANCEL
| _IO_FLAGS2_CLOEXEC);
result = _IO_file_fopen (fp, gfilename, mode, 0);
fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE;
if (result != NULL)

View File

@ -308,9 +308,7 @@ do_test (void)
TEST_VERIFY_EXIT (fp != NULL);
ret = fcntl (fileno (fp), F_GETFD);
TEST_VERIFY (ret != -1);
#if 0 /* Fails to clear FD_CLOEXEC (bug 32134). */
TEST_COMPARE (ret & FD_CLOEXEC, 0);
#endif
TEST_COMPARE_FILE_STRING (fp, "plustomore");
xfclose (fp);
END_TEST;