Os: add Nanosleep()

Add Nanosleep(), so that upper layers of wifilogd can
briefly suspend execution after a transient error.

Bug: 32454491
Test: ./runtest.sh (on angler)
Change-Id: I85e95ddf4139ae10ab95a40c46ed2a424e2a28ad
diff --git a/os.cpp b/os.cpp
index ab178c1..b9093e7 100644
--- a/os.cpp
+++ b/os.cpp
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-#include <errno.h>
-
 #include <algorithm>
+#include <cerrno>
 #include <cstdint>
+#include <cstring>
 
 #include "android-base/logging.h"
 
@@ -70,6 +70,26 @@
   return now_timestamp;
 }
 
+void Os::Nanosleep(uint32_t sleep_time_nsec) {
+  struct timespec sleep_timespec = {
+      0,  // tv_sec
+      SAFELY_CLAMP(sleep_time_nsec, decltype(timespec::tv_nsec), 0, kMaxNanos)};
+
+  int failed = 0;
+  do {
+    struct timespec remaining_timespec;
+    failed = raw_os_->Nanosleep(&sleep_timespec, &remaining_timespec);
+    sleep_timespec = remaining_timespec;
+  } while (failed && errno == EINTR && sleep_timespec.tv_nsec > 0);
+
+  if (failed && errno != EINTR) {
+    // The only other documented errors for the underlying nanosleep() call are
+    // EFAULT and EINVAL. But we always pass valid pointers, and the values in
+    // |sleep_timespec| are always valid.
+    LOG(FATAL) << "Unexpected error: " << std::strerror(errno);
+  }
+}
+
 std::tuple<size_t, Os::Errno> Os::ReceiveDatagram(int fd, void* buf,
                                                   size_t buflen) {
   // recv() takes a size_t, but returns an ssize_t. That means that the largest