pw_build: Detect EOF on macOS in pw-wrap-ninja

Previously, we relied on Python throwing an OSError when we attempted to
read from the Ninja subprocess's stdout to know if it closed its side of
the TTY.

This doesn't work on macOS -- instead, `read` returns an empty string.
This commit checks for both, preventing the issue where pw-wrap-ninja
would hang indefinitely when running it on macOS.

Change-Id: Ib8fca3e75197848c8aa2df733357010031c96959
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/126921
Pigweed-Auto-Submit: Eli Lipsitz <elipsitz@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
Reviewed-by: Rob Mohr <mohrr@google.com>
diff --git a/pw_build/py/pw_build/wrap_ninja.py b/pw_build/py/pw_build/wrap_ninja.py
index bbbc727..e7a0f49 100644
--- a/pw_build/py/pw_build/wrap_ninja.py
+++ b/pw_build/py/pw_build/wrap_ninja.py
@@ -290,6 +290,9 @@
                     self._process_output(''.join(buffer))
                     buffer = []
                     continue
+                if char == '':
+                    # End of file.
+                    break
 
                 # Look for the end of a status line, ignoring partial matches.
                 if char == '\x1B' and ninja_status:
@@ -307,7 +310,10 @@
 
                 buffer.append(char)
         except OSError:
-            self.exited = True
+            pass
+
+        self._process_output(''.join(buffer))
+        self.exited = True
 
     def _process_output(self, line: str) -> None:
         """Process a line of output from Ninja, updating the internal state."""