tinycpp
tinycpp copied to clipboard
preproc: freopen_r(): avoid crash on macOS [13.3.1(a)] where fmemopen(buf, 0, "r") is not allowed.
(cherry picked from commit e7cb2ed116ad7747bef8cebc2c4acc40be7a8dfa)
On macOS 13.3.1(a) [arm64], I was hitting a crash due to freopen_r() returning null during expansion of empty macros, e.g.
#define EXTRA_LONG
I looked into this a bit and found it was the result of fmemopen(but, 0, "r") failing with EINVAL, as is allowed (and was once required, but is no longer) by the POSIX spec.
See https://github.com/apple-oss-distributions/Libc/blob/7861c72b1692b65f79c03f21a8a1a8e51e14c843/stdio/FreeBSD/fmemopen.c#LL59C1-L65C3
The history of this behavior in glibc and POSIX can be found here: https://sourceware.org/bugzilla/show_bug.cgi?id=11216
I filed a problem report with Apple about this (FB12182362), but in the meantime, I needed to work around this behavior on macOS and found that allocating a 1-byte buffer and then using the "w+" mode to truncate the stream to zero length, while still allowing read access, works for this purpose.