1515
1616namespace LIBC_NAMESPACE_DECL {
1717
18- namespace {
19-
20- // TODO: this is copied from `puts`, it should be moved to a shared utility.
21- // Simple helper to unlock the file once destroyed.
22- struct ScopedLock {
23- ScopedLock (LIBC_NAMESPACE::File *stream) : stream(stream) { stream->lock (); }
24- ~ScopedLock () { stream->unlock (); }
25-
26- private:
27- LIBC_NAMESPACE::File *stream;
28- };
29-
3018int write_out (cpp::string_view str_view, File *f) {
3119 if (str_view.size () > 0 ) {
3220 auto result = f->write_unlocked (str_view.data (), str_view.size ());
@@ -36,21 +24,12 @@ int write_out(cpp::string_view str_view, File *f) {
3624 return 0 ;
3725}
3826
39- } // namespace
40-
41- // TODO: this seems like there should be some sort of queue system to
42- // deduplicate this code.
43- LLVM_LIBC_FUNCTION (void , perror, (const char *str)) {
44- const char empty_str[1 ] = {' \0 ' };
45- if (str == nullptr )
46- str = empty_str;
47- cpp::string_view str_view (str);
48-
49- auto err_str = get_error_string (libc_errno);
50-
51- // We need to lock the stream to ensure the newline is always appended.
52- ScopedLock lock (LIBC_NAMESPACE::stderr);
27+ // separate function so that we can return early on error but still get the
28+ // unlock. This function sets errno and should not be called elsewhere.
29+ void write_sequence (cpp::string_view str_view, cpp::string_view err_str) {
5330 int write_err;
31+ // TODO: this seems like there should be some sort of queue system to
32+ // deduplicate this code.
5433
5534 // FORMAT:
5635 // if str != nullptr and doesn't start with a null byte:
@@ -84,4 +63,18 @@ LLVM_LIBC_FUNCTION(void, perror, (const char *str)) {
8463 }
8564}
8665
66+ LLVM_LIBC_FUNCTION (void , perror, (const char *str)) {
67+ const char empty_str[1 ] = {' \0 ' };
68+ if (str == nullptr )
69+ str = empty_str;
70+ cpp::string_view str_view (str);
71+
72+ cpp::string_view err_str = get_error_string (libc_errno);
73+
74+ // We need to lock the stream to ensure the newline is always appended.
75+ LIBC_NAMESPACE::stderr->lock ();
76+ write_sequence (str_view, err_str);
77+ LIBC_NAMESPACE::stderr->unlock ();
78+ }
79+
8780} // namespace LIBC_NAMESPACE_DECL
0 commit comments