]> gitweb.factorcode.org Git - factor.git/blobdiff - vm/os-linux.cpp
io.streams.256color: faster by caching styles
[factor.git] / vm / os-linux.cpp
index ebbbf7a6febe455508eaa45ec26c56a03b3fcbd3..0261942462c6bd8b778f23b944862681cbb71ab7 100644 (file)
@@ -1,27 +1,32 @@
 #include "master.hpp"
 
-namespace factor
-{
+namespace factor {
 
-/* Snarfed from SBCL linux-so.c. You must free() the result yourself. */
-const char *vm_executable_path()
-{
-       char *path = new char[PATH_MAX + 1];
+const char* vm_executable_path() {
+  ssize_t bufsiz = 4096;
 
-       int size = readlink("/proc/self/exe", path, PATH_MAX);
-       if (size < 0)
-       {
-               fatal_error("Cannot read /proc/self/exe",0);
-               return NULL;
-       }
-       else
-       {
-               path[size] = '\0';
-
-               const char *ret = safe_strdup(path);
-               delete[] path;
-               return ret;
-       }
+  // readlink is called in a loop with increasing buffer sizes in case
+  // someone tries to run Factor from a incredibly deeply nested
+  // path.
+  while (true) {
+    char* buf = new char[bufsiz + 1];
+    ssize_t size= readlink("/proc/self/exe", buf, bufsiz);
+    if (size < 0) {
+      fatal_error("Cannot read /proc/self/exe", errno);
+    } else {
+      if (size < bufsiz) {
+        // Buffer was large enough, return string.
+        buf[size] = '\0';
+        const char* ret = safe_strdup(buf);
+        delete[] buf;
+        return ret;
+      } else {
+        // Buffer wasn't big enough, double it and try again.
+        delete[] buf;
+        bufsiz *= 2;
+      }
+    }
+  }
 }
 
 }