+ delete[] lpVersionInfo;
+ delete[] filePath;
+
+ return oss.str();
+#else
+ struct utsname osinfo;
+ uname(&osinfo);
+ return std::string(osinfo.sysname) + "/"
+ + osinfo.release + " " + osinfo.machine;
+#endif
+}
+
+
+bool getCurrentWorkingDir(char *buf, size_t len)
+{
+#ifdef _WIN32
+ DWORD ret = GetCurrentDirectory(len, buf);
+ return (ret != 0) && (ret <= len);
+#else
+ return getcwd(buf, len);
+#endif
+}
+
+
+bool getExecPathFromProcfs(char *buf, size_t buflen)
+{
+#ifndef _WIN32
+ buflen--;
+
+ ssize_t len;
+ if ((len = readlink("/proc/self/exe", buf, buflen)) == -1 &&
+ (len = readlink("/proc/curproc/file", buf, buflen)) == -1 &&
+ (len = readlink("/proc/curproc/exe", buf, buflen)) == -1)
+ return false;
+
+ buf[len] = '\0';
+ return true;
+#else
+ return false;
+#endif
+}
+
+//// Windows
+#if defined(_WIN32)
+
+bool getCurrentExecPath(char *buf, size_t len)
+{
+ DWORD written = GetModuleFileNameA(NULL, buf, len);
+ if (written == 0 || written == len)
+ return false;
+
+ return true;
+}
+
+
+//// Linux
+#elif defined(__linux__)
+
+bool getCurrentExecPath(char *buf, size_t len)
+{
+ if (!getExecPathFromProcfs(buf, len))
+ return false;
+
+ return true;
+}
+
+
+//// Mac OS X, Darwin
+#elif defined(__APPLE__)
+
+bool getCurrentExecPath(char *buf, size_t len)
+{
+ uint32_t lenb = (uint32_t)len;
+ if (_NSGetExecutablePath(buf, &lenb) == -1)
+ return false;
+
+ return true;
+}
+
+
+//// FreeBSD, NetBSD, DragonFlyBSD
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+
+bool getCurrentExecPath(char *buf, size_t len)
+{
+ // Try getting path from procfs first, since valgrind
+ // doesn't work with the latter
+ if (getExecPathFromProcfs(buf, len))
+ return true;
+
+ int mib[4];
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PATHNAME;
+ mib[3] = -1;
+
+ if (sysctl(mib, 4, buf, &len, NULL, 0) == -1)
+ return false;
+
+ return true;
+}
+
+#elif defined(__HAIKU__)
+
+bool getCurrentExecPath(char *buf, size_t len)
+{
+ return find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, NULL, buf, len) == B_OK;
+}
+
+//// Solaris
+#elif defined(__sun) || defined(sun)
+
+bool getCurrentExecPath(char *buf, size_t len)
+{
+ const char *exec = getexecname();
+ if (exec == NULL)
+ return false;
+
+ if (strlcpy(buf, exec, len) >= len)
+ return false;
+
+ return true;
+}
+
+
+// HP-UX
+#elif defined(__hpux)
+
+bool getCurrentExecPath(char *buf, size_t len)
+{
+ struct pst_status psts;
+
+ if (pstat_getproc(&psts, sizeof(psts), 0, getpid()) == -1)
+ return false;
+
+ if (pstat_getpathname(buf, len, &psts.pst_fid_text) == -1)
+ return false;
+
+ return true;
+}
+
+
+#else
+
+bool getCurrentExecPath(char *buf, size_t len)
+{
+ return false;
+}
+
+#endif
+
+
+//// Non-Windows
+#if !defined(_WIN32)
+
+const char *getHomeOrFail()
+{
+ const char *home = getenv("HOME");
+ // In rare cases the HOME environment variable may be unset
+ FATAL_ERROR_IF(!home,
+ "Required environment variable HOME is not set");
+ return home;
+}