#include "master.hpp"
-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];
-
- 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;
- }
-}
-
-#ifdef SYS_inotify_init
-
-VM_C_API int inotify_init()
-{
- return syscall(SYS_inotify_init);
-}
-
-VM_C_API int inotify_add_watch(int fd, const char *name, u32 mask)
-{
- return syscall(SYS_inotify_add_watch, fd, name, mask);
-}
-
-VM_C_API int inotify_rm_watch(int fd, u32 wd)
-{
- return syscall(SYS_inotify_rm_watch, fd, wd);
+namespace factor {
+
+const char* vm_executable_path() {
+ ssize_t bufsiz = 4096;
+
+ // 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;
+ }
+ }
+ }
}
-#else
-
-VM_C_API int inotify_init()
-{
- myvm->not_implemented_error();
- return -1;
-}
-
-VM_C_API int inotify_add_watch(int fd, const char *name, u32 mask)
-{
- myvm->not_implemented_error();
- return -1;
-}
-
-VM_C_API int inotify_rm_watch(int fd, u32 wd)
-{
- myvm->not_implemented_error();
- return -1;
-}
-
-#endif
-
}