vmbase: bionic: Log fputs(), fwrite(), perror()

As the vmbase entry code ensures that no C code will run before the
logger has been initialized, use the log crate directly from the Bionic
stubs instead of calling the console functions directly.

Test: m pvmfw librialto libvmbase_example
Change-Id: Ia441e44eb70506220a28fde193355d1a2fe79d19
diff --git a/vmbase/src/bionic.rs b/vmbase/src/bionic.rs
index a38fd25..1ed6bd6 100644
--- a/vmbase/src/bionic.rs
+++ b/vmbase/src/bionic.rs
@@ -14,7 +14,6 @@
 
 //! Low-level compatibility layer between baremetal Rust and Bionic C functions.
 
-use crate::console;
 use crate::eprintln;
 use crate::rand::fill_with_entropy;
 use crate::read_sysreg;
@@ -27,6 +26,8 @@
 use core::str;
 
 use cstr::cstr;
+use log::error;
+use log::info;
 
 const EOF: c_int = -1;
 const EIO: c_int = 5;
@@ -130,6 +131,23 @@
     Stderr = 0x9d118200,
 }
 
+impl File {
+    fn write_lines(&self, s: &str) {
+        for line in s.split_inclusive('\n') {
+            let (line, ellipsis) = if let Some(stripped) = line.strip_suffix('\n') {
+                (stripped, "")
+            } else {
+                (line, " ...")
+            };
+
+            match self {
+                Self::Stdout => info!("{line}{ellipsis}"),
+                Self::Stderr => error!("{line}{ellipsis}"),
+            }
+        }
+    }
+}
+
 impl TryFrom<usize> for File {
     type Error = &'static str;
 
@@ -152,8 +170,8 @@
     // SAFETY: Just like libc, we need to assume that `s` is a valid NULL-terminated string.
     let c_str = unsafe { CStr::from_ptr(c_str) };
 
-    if let (Ok(s), Ok(_)) = (c_str.to_str(), File::try_from(stream)) {
-        console::write_str(s);
+    if let (Ok(s), Ok(f)) = (c_str.to_str(), File::try_from(stream)) {
+        f.write_lines(s);
         0
     } else {
         set_errno(EOF);
@@ -168,8 +186,8 @@
     // SAFETY: Just like libc, we need to assume that `ptr` is valid.
     let bytes = unsafe { slice::from_raw_parts(ptr as *const u8, length) };
 
-    if let (Ok(s), Ok(_)) = (str::from_utf8(bytes), File::try_from(stream)) {
-        console::write_str(s);
+    if let (Ok(s), Ok(f)) = (str::from_utf8(bytes), File::try_from(stream)) {
+        f.write_lines(s);
         length
     } else {
         0