From e02797df909c686fe2fcf1afca15883cbe071a68 Mon Sep 17 00:00:00 2001
From: Avi Kivity <avi.kivity@gmail.com>
Date: Sun, 6 Jan 2013 17:12:18 +0200
Subject: [PATCH] libc: implement realpath()

Assumes no symlinks, cwd == /.
---
 libc/libc.cc | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/libc/libc.cc b/libc/libc.cc
index df5bc3e94..88119b1cd 100644
--- a/libc/libc.cc
+++ b/libc/libc.cc
@@ -1,5 +1,8 @@
 #include "libc.hh"
 #include <stdio.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <boost/algorithm/string/split.hpp>
 
 int libc_error(int err)
 {
@@ -15,3 +18,33 @@ int* __errno_location()
 {
     return &errno;
 }
+
+char* realpath(const char* path, char* resolved_path)
+{
+    // assumes cwd == /
+    std::vector<std::string> components;
+    std::string spath = path;
+    boost::split(components, spath, [] (char c) { return c == '/'; });
+    std::vector<std::string> tmp;
+    for (auto c : components) {
+        if (c == "" || c == ".") {
+            continue;
+        } else if (c == "..") {
+            if (!tmp.empty()) {
+                tmp.pop_back();
+            }
+        } else {
+            tmp.push_back(c);
+        }
+    }
+    std::string ret;
+    for (auto c : tmp) {
+        ret += "/" + c;
+    }
+    ret = ret.substr(0, PATH_MAX - 1);
+    if (!resolved_path) {
+        resolved_path = static_cast<char*>(malloc(ret.size() + 1));
+    }
+    strcpy(resolved_path, ret.c_str());
+    return resolved_path;
+}
-- 
GitLab