Skip to content

Commit 4fb7b33

Browse files
authored
[libc++][print] Moves is_terminal to the dylib. (#80464)
Having the test in the header requires including unistd.h on POSIX platforms. This header has other declarations which may conflict with code that uses named declarations provided by this header. For example code using "int pipe;" would conflict with the function pipe in this header. Moving the code to the dylib means std::print would not be available on Apple backdeployment targets. On POSIX platforms there is no transcoding required so a not Standard conforming implementation is still a useful and the observable differences are minimal. This behaviour has been done for print before #76293. Note questions have been raised in LWG4044 "Confusing requirements for std::print on POSIX platforms", whether or not the isatty check on POSIX platforms is required. When this LWG issue is resolved the backdeployment targets could become Standard compliant. This patch is intended to be backported to the LLVM-18 branch. Fixes: #79782
1 parent a4ac099 commit 4fb7b33

12 files changed

+40
-16
lines changed

libcxx/include/print

+7-7
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ namespace std {
3232
*/
3333

3434
#include <__assert> // all public C++ headers provide the assertion handler
35+
#include <__availability>
3536
#include <__concepts/same_as.h>
3637
#include <__config>
3738
#include <__system_error/system_error.h>
@@ -43,10 +44,6 @@ namespace std {
4344
#include <string_view>
4445
#include <version>
4546

46-
#if __has_include(<unistd.h>)
47-
# include <unistd.h>
48-
#endif
49-
5047
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5148
# pragma GCC system_header
5249
#endif
@@ -68,7 +65,8 @@ _LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream);
6865
// Note the function is only implemented on the Windows platform.
6966
_LIBCPP_EXPORTED_FROM_ABI void __write_to_windows_console(FILE* __stream, wstring_view __view);
7067
# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
71-
68+
#elif __has_include(<unistd.h>)
69+
_LIBCPP_EXPORTED_FROM_ABI bool __is_posix_terminal(FILE* __stream);
7270
#endif // _LIBCPP_WIN32API
7371

7472
#if _LIBCPP_STD_VER >= 23
@@ -195,15 +193,17 @@ inline constexpr bool __use_unicode_execution_charset = _MSVC_EXECUTION_CHARACTE
195193
inline constexpr bool __use_unicode_execution_charset = true;
196194
# endif
197195

198-
_LIBCPP_HIDE_FROM_ABI inline bool __is_terminal(FILE* __stream) {
196+
_LIBCPP_HIDE_FROM_ABI inline bool __is_terminal([[maybe_unused]] FILE* __stream) {
199197
// The macro _LIBCPP_TESTING_PRINT_IS_TERMINAL is used to change
200198
// the behavior in the test. This is not part of the public API.
201199
# ifdef _LIBCPP_TESTING_PRINT_IS_TERMINAL
202200
return _LIBCPP_TESTING_PRINT_IS_TERMINAL(__stream);
201+
# elif _LIBCPP_AVAILABILITY_HAS_PRINT == 0
202+
return false;
203203
# elif defined(_LIBCPP_WIN32API)
204204
return std::__is_windows_terminal(__stream);
205205
# elif __has_include(<unistd.h>)
206-
return isatty(fileno(__stream));
206+
return std::__is_posix_terminal(__stream);
207207
# else
208208
# error "Provide a way to determine whether a FILE* is a terminal"
209209
# endif

libcxx/lib/abi/CHANGELOG.TXT

+8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ New entries should be added directly below the "Version" header.
1616
Version 18.0
1717
------------
1818

19+
* [libc++] Moves is_terminal to the dylib
20+
21+
The patch moves the POSIX implementation of is_terminal to the dylib. This is
22+
needed to avoid using <unistd.h> in public headers.
23+
24+
All platforms
25+
Symbol added: _ZNSt6__ndk119__is_posix_terminalEP7__sFILE
26+
1927
* [libc++abi] Implement __cxa_init_primary_exception and use it to optimize std::make_exception_ptr (#65534)
2028

2129
This patch implements __cxa_init_primary_exception, an extension to the Itanium C++ ABI.

libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,7 @@
14951495
{'is_defined': True, 'name': '__ZNSt3__118shared_timed_mutex8try_lockEv', 'type': 'FUNC'}
14961496
{'is_defined': True, 'name': '__ZNSt3__118shared_timed_mutexC1Ev', 'type': 'FUNC'}
14971497
{'is_defined': True, 'name': '__ZNSt3__118shared_timed_mutexC2Ev', 'type': 'FUNC'}
1498+
{'is_defined': True, 'name': '__ZNSt3__119__is_posix_terminalEP7__sFILE', 'type': 'FUNC'}
14981499
{'is_defined': True, 'name': '__ZNSt3__119__shared_mutex_base11lock_sharedEv', 'type': 'FUNC'}
14991500
{'is_defined': True, 'name': '__ZNSt3__119__shared_mutex_base13unlock_sharedEv', 'type': 'FUNC'}
15001501
{'is_defined': True, 'name': '__ZNSt3__119__shared_mutex_base15try_lock_sharedEv', 'type': 'FUNC'}

libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,7 @@
11761176
{'is_defined': True, 'name': '_ZNSt6__ndk118shared_timed_mutex8try_lockEv', 'type': 'FUNC'}
11771177
{'is_defined': True, 'name': '_ZNSt6__ndk118shared_timed_mutexC1Ev', 'type': 'FUNC'}
11781178
{'is_defined': True, 'name': '_ZNSt6__ndk118shared_timed_mutexC2Ev', 'type': 'FUNC'}
1179+
{'is_defined': True, 'name': '_ZNSt6__ndk119__is_posix_terminalEP7__sFILE', 'type': 'FUNC'}
11791180
{'is_defined': True, 'name': '_ZNSt6__ndk119__shared_mutex_base11lock_sharedEv', 'type': 'FUNC'}
11801181
{'is_defined': True, 'name': '_ZNSt6__ndk119__shared_mutex_base13unlock_sharedEv', 'type': 'FUNC'}
11811182
{'is_defined': True, 'name': '_ZNSt6__ndk119__shared_mutex_base15try_lock_sharedEv', 'type': 'FUNC'}

libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@
534534
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutex8try_lockEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
535535
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutexC1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
536536
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutexC2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
537+
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__119__is_posix_terminalEP4FILE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
537538
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base11lock_sharedEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
538539
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base13unlock_sharedEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
539540
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base15try_lock_sharedEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}

libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@
534534
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutex8try_lockEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
535535
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutexC1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
536536
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutexC2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
537+
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__119__is_posix_terminalEP4FILE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
537538
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base11lock_sharedEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
538539
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base13unlock_sharedEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
539540
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base15try_lock_sharedEv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}

libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,7 @@
14951495
{'is_defined': True, 'name': '__ZNSt3__118shared_timed_mutex8try_lockEv', 'type': 'FUNC'}
14961496
{'is_defined': True, 'name': '__ZNSt3__118shared_timed_mutexC1Ev', 'type': 'FUNC'}
14971497
{'is_defined': True, 'name': '__ZNSt3__118shared_timed_mutexC2Ev', 'type': 'FUNC'}
1498+
{'is_defined': True, 'name': '__ZNSt3__119__is_posix_terminalEP7__sFILE', 'type': 'FUNC'}
14981499
{'is_defined': True, 'name': '__ZNSt3__119__shared_mutex_base11lock_sharedEv', 'type': 'FUNC'}
14991500
{'is_defined': True, 'name': '__ZNSt3__119__shared_mutex_base13unlock_sharedEv', 'type': 'FUNC'}
15001501
{'is_defined': True, 'name': '__ZNSt3__119__shared_mutex_base15try_lock_sharedEv', 'type': 'FUNC'}

libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,7 @@
11761176
{'is_defined': True, 'name': '_ZNSt6__ndk118shared_timed_mutex8try_lockEv', 'type': 'FUNC'}
11771177
{'is_defined': True, 'name': '_ZNSt6__ndk118shared_timed_mutexC1Ev', 'type': 'FUNC'}
11781178
{'is_defined': True, 'name': '_ZNSt6__ndk118shared_timed_mutexC2Ev', 'type': 'FUNC'}
1179+
{'is_defined': True, 'name': '_ZNSt6__ndk119__is_posix_terminalEP7__sFILE', 'type': 'FUNC'}
11791180
{'is_defined': True, 'name': '_ZNSt6__ndk119__shared_mutex_base11lock_sharedEv', 'type': 'FUNC'}
11801181
{'is_defined': True, 'name': '_ZNSt6__ndk119__shared_mutex_base13unlock_sharedEv', 'type': 'FUNC'}
11811182
{'is_defined': True, 'name': '_ZNSt6__ndk119__shared_mutex_base15try_lock_sharedEv', 'type': 'FUNC'}

libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,7 @@
11901190
{'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutex8try_lockEv', 'type': 'FUNC'}
11911191
{'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutexC1Ev', 'type': 'FUNC'}
11921192
{'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutexC2Ev', 'type': 'FUNC'}
1193+
{'is_defined': True, 'name': '_ZNSt3__119__is_posix_terminalEP7__sFILE', 'type': 'FUNC'}
11931194
{'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base11lock_sharedEv', 'type': 'FUNC'}
11941195
{'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base13unlock_sharedEv', 'type': 'FUNC'}
11951196
{'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base15try_lock_sharedEv', 'type': 'FUNC'}

libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,7 @@
11881188
{'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutex8try_lockEv', 'type': 'FUNC'}
11891189
{'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutexC1Ev', 'type': 'FUNC'}
11901190
{'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutexC2Ev', 'type': 'FUNC'}
1191+
{'is_defined': True, 'name': '_ZNSt3__119__is_posix_terminalEP8_IO_FILE', 'type': 'FUNC'}
11911192
{'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base11lock_sharedEv', 'type': 'FUNC'}
11921193
{'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base13unlock_sharedEv', 'type': 'FUNC'}
11931194
{'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base15try_lock_sharedEv', 'type': 'FUNC'}

libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist

+1
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,7 @@
11591159
{'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutex8try_lockEv', 'type': 'FUNC'}
11601160
{'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutexC1Ev', 'type': 'FUNC'}
11611161
{'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutexC2Ev', 'type': 'FUNC'}
1162+
{'is_defined': True, 'name': '_ZNSt3__119__is_posix_terminalEP8_IO_FILE', 'type': 'FUNC'}
11621163
{'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base11lock_sharedEv', 'type': 'FUNC'}
11631164
{'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base13unlock_sharedEv', 'type': 'FUNC'}
11641165
{'is_defined': True, 'name': '_ZNSt3__119__shared_mutex_base15try_lock_sharedEv', 'type': 'FUNC'}

libcxx/src/print.cpp

+16-9
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,26 @@
88

99
#include <__config>
1010

11-
#if defined(_LIBCPP_WIN32API)
11+
#include <cstdlib>
12+
#include <print>
13+
14+
#include <__system_error/system_error.h>
1215

13-
# include <cstdlib>
14-
# include <print>
16+
#include "filesystem/error.h"
1517

18+
#if defined(_LIBCPP_WIN32API)
1619
# define WIN32_LEAN_AND_MEAN
1720
# define NOMINMAX
1821
# include <io.h>
1922
# include <windows.h>
20-
21-
# include <__system_error/system_error.h>
22-
23-
# include "filesystem/error.h"
23+
#elif __has_include(<unistd.h>)
24+
# include <unistd.h>
25+
#endif
2426

2527
_LIBCPP_BEGIN_NAMESPACE_STD
2628

29+
#if defined(_LIBCPP_WIN32API)
30+
2731
_LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream) {
2832
// Note the Standard does this in one call, but it's unclear whether
2933
// an invalid handle is allowed when calling GetConsoleMode.
@@ -52,6 +56,9 @@ __write_to_windows_console([[maybe_unused]] FILE* __stream, [[maybe_unused]] wst
5256
}
5357
# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5458

55-
_LIBCPP_END_NAMESPACE_STD
59+
#elif __has_include(<unistd.h>) // !_LIBCPP_WIN32API
5660

57-
#endif // !_LIBCPP_WIN32API
61+
_LIBCPP_EXPORTED_FROM_ABI bool __is_posix_terminal(FILE* __stream) { return isatty(fileno(__stream)); }
62+
#endif
63+
64+
_LIBCPP_END_NAMESPACE_STD

0 commit comments

Comments
 (0)