diff -r 01f88c3b7b66 -r 1b2b84315d27 misc/libphysfs/platform_unix.c --- a/misc/libphysfs/platform_unix.c Thu Aug 11 23:05:14 2016 +0300 +++ b/misc/libphysfs/platform_unix.c Sun Dec 17 00:09:24 2017 +0100 @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #if PHYSFS_PLATFORM_LINUX && !defined(PHYSFS_HAVE_MNTENT_H) #define PHYSFS_HAVE_MNTENT_H 1 @@ -171,7 +173,7 @@ binlen = strlen(bin); size = strlen(start) + binlen + 2; - if (size > alloc_size) + if (size >= alloc_size) { char *x = (char *) allocator.Realloc(exe, size); if (!x) @@ -193,7 +195,7 @@ if (access(exe, X_OK) == 0) /* Exists as executable? We're done. */ { - exe[size - binlen - 1] = '\0'; /* chop off filename, leave '/' */ + exe[(size - binlen) - 1] = '\0'; /* chop off filename, leave '/' */ return exe; } /* if */ @@ -244,20 +246,45 @@ char *retval = NULL; const char *envr = NULL; - /* - * Try to avoid using argv0 unless forced to. If there's a Linux-like - * /proc filesystem, you can get the full path to the current process from - * the /proc/self/exe symlink. + /* Try to avoid using argv0 unless forced to. Try system-specific stuff. */ + + #if PHYSFS_PLATFORM_FREEBSD + { + char fullpath[PATH_MAX]; + size_t buflen = sizeof (fullpath); + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; + if (sysctl(mib, 4, fullpath, &buflen, NULL, 0) != -1) + retval = __PHYSFS_strdup(fullpath); + } + #elif PHYSFS_PLATFORM_SOLARIS + { + const char *path = getexecname(); + if ((path != NULL) && (path[0] == '/')) /* must be absolute path... */ + retval = __PHYSFS_strdup(path); + } + #endif + + if (retval) + return retval; /* already got it. */ + + /* If there's a Linux-like /proc filesystem, you can get the full path to + * the current process from a symlink in there. */ - retval = readSymLink("/proc/self/exe"); - if (retval == NULL) + + if (access("/proc", F_OK) == 0) { - /* older kernels don't have /proc/self ... try PID version... */ - const unsigned long long pid = (unsigned long long) getpid(); - char path[64]; - const int rc = (int) snprintf(path,sizeof(path),"/proc/%llu/exe",pid); - if ( (rc > 0) && (rc < sizeof(path)) ) - retval = readSymLink(path); + retval = readSymLink("/proc/self/exe"); + if (!retval) retval = readSymLink("/proc/curproc/file"); + if (!retval) retval = readSymLink("/proc/curproc/exe"); + if (retval == NULL) + { + /* older kernels don't have /proc/self ... try PID version... */ + const unsigned long long pid = (unsigned long long) getpid(); + char path[64]; + const int rc = (int) snprintf(path,sizeof(path),"/proc/%llu/exe",pid); + if ( (rc > 0) && (rc < sizeof(path)) ) + retval = readSymLink(path); + } /* if */ } /* if */ if (retval != NULL) /* chop off filename. */ @@ -272,7 +299,7 @@ } /* else */ } /* if */ - /* No /proc/self/exe, but we have an argv[0] we can parse? */ + /* No /proc/self/exe, etc, but we have an argv[0] we can parse? */ if ((retval == NULL) && (argv0 != NULL)) { /* fast path: default behaviour can handle this. */ @@ -310,7 +337,7 @@ * This isn't strictly correct, but the results are relatively sane * in any case. * - * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + * https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html */ const char *envr = getenv("XDG_DATA_HOME"); const char *append = "/";