fixed lots of not-thread-safe things
Most of the things I fixed here were using libc functions that are
fundamentally not thread-safe.
diff --git a/aos/common/libc/dirname.cc b/aos/common/libc/dirname.cc
new file mode 100644
index 0000000..c843898
--- /dev/null
+++ b/aos/common/libc/dirname.cc
@@ -0,0 +1,39 @@
+#include "aos/common/libc/dirname.h"
+
+namespace aos {
+namespace libc {
+namespace {
+
+::std::string DoDirname(const ::std::string &path, size_t last_slash) {
+ // If there aren't any other '/'s in it.
+ if (last_slash == ::std::string::npos) return ".";
+
+ // Back up as long as we see '/'s.
+ do {
+ // If we get all the way to the beginning.
+ if (last_slash == 0) return "/";
+ --last_slash;
+ } while (path[last_slash] == '/');
+
+ return path.substr(0, last_slash + 1);
+}
+
+} // namespace
+
+::std::string Dirname(const ::std::string &path) {
+ // Without this, we end up with integer underflows below, which is technically
+ // undefined.
+ if (path.size() == 0) return ".";
+
+ size_t last_slash = path.rfind('/');
+
+ // If the path ends with a '/'.
+ if (last_slash == path.size() - 1) {
+ last_slash = DoDirname(path, last_slash).rfind('/');
+ }
+
+ return DoDirname(path, last_slash);
+}
+
+} // namespace libc
+} // namespace aos