Skip to content

Conversation

@wecing
Copy link
Contributor

@wecing wecing commented Nov 5, 2025

See 1 and 2. isatty() is part of unistd.h, but fileno() is in stdio.h, and is guarded by _POSIX_C_SOURCE >= 1 (on my machine, man 3 fileno only requires defined(_POSIX_C_SOURCE), though).

I ran into this issue while trying to compile libc++ for a bare metal environment with Newlib as the libc. Newlib defines fileno() in stdio.h, and its unistd.h does not include stdio.h.

See [1] and [2]. isatty() is part of unistd.h, but fileno() is in
stdio.h, and is guarded by `_POSIX_C_SOURCE >= 1` (on my machine,
`man 3 fileno` only requires `defined(_POSIX_C_SOURCE)`, though).

I ran into this issue while trying to compile libc++ for a bare metal
environment with Newlib as the libc. Newlib defines fileno() in stdio.h,
and its unistd.h does not include stdio.h.

[1]: https://linux.die.net/man/3/fileno
[2]: https://linux.die.net/man/3/isatty
@wecing wecing requested review from ldionne and mordante November 5, 2025 23:32
@wecing wecing requested a review from a team as a code owner November 5, 2025 23:32
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Nov 5, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 5, 2025

@llvm/pr-subscribers-libcxx

Author: Chenguang Wang (wecing)

Changes

See 1 and 2. isatty() is part of unistd.h, but fileno() is in stdio.h, and is guarded by _POSIX_C_SOURCE >= 1 (on my machine, man 3 fileno only requires defined(_POSIX_C_SOURCE), though).

I ran into this issue while trying to compile libc++ for a bare metal environment with Newlib as the libc. Newlib defines fileno() in stdio.h, and its unistd.h does not include stdio.h.


Full diff: https://github.com/llvm/llvm-project/pull/166668.diff

1 Files Affected:

  • (modified) libcxx/src/print.cpp (+5-2)
diff --git a/libcxx/src/print.cpp b/libcxx/src/print.cpp
index 3f2baa6dcc60b..e7ff60ba58dac 100644
--- a/libcxx/src/print.cpp
+++ b/libcxx/src/print.cpp
@@ -20,8 +20,11 @@
 #  define NOMINMAX
 #  include <io.h>
 #  include <windows.h>
-#elif __has_include(<unistd.h>)
+#elif __has_include(<unistd.h>) && __has_include(<stdio.h>) && \
+      defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 1
+#  include <stdio.h>
 #  include <unistd.h>
+#  define HAS_FILENO_AND_ISATTY
 #endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
@@ -56,7 +59,7 @@ __write_to_windows_console([[maybe_unused]] FILE* __stream, [[maybe_unused]] wst
 }
 #  endif // _LIBCPP_HAS_WIDE_CHARACTERS
 
-#elif __has_include(<unistd.h>) // !_LIBCPP_WIN32API
+#elif defined(HAS_FILENO_AND_ISATTY) // !_LIBCPP_WIN32API
 
 _LIBCPP_EXPORTED_FROM_ABI bool __is_posix_terminal(FILE* __stream) { return isatty(fileno(__stream)); }
 #endif

@wecing
Copy link
Contributor Author

wecing commented Nov 6, 2025

Looks like this commit broke macos, freebsd, and android. Need to investigate how to guard properly on these platforms.

@wecing
Copy link
Contributor Author

wecing commented Nov 7, 2025

Updated the implementation, and tests seem to be passing now.

I added a special handling logic for Newlib only; other platforms should not be affected. The defined(_NEWLIB_VERSION) trick is used in other places within libc++ as well, e.g. here.

The _NEWLIB_VERSION symbol will be visible if you include e.g. Newlib's unistd.h. Newlib's fileno is guarded by __POSIX_VISIBLE.

@wecing wecing merged commit a3058d5 into llvm:main Nov 12, 2025
80 checks passed
git-crd pushed a commit to git-crd/crd-llvm-project that referenced this pull request Nov 13, 2025
…m#166668)

Including unistd.h does not expose fileno() on Newlib.
@philnik777
Copy link
Contributor

@wecing Reviews in libc++ aren't optional. Please wait next time. If you don't get any comments within a week feel free to ping.

@wecing
Copy link
Contributor Author

wecing commented Nov 13, 2025

@wecing Reviews in libc++ aren't optional. Please wait next time. If you don't get any comments within a week feel free to ping.

I see. My apologies! Thanks for letting me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants