Fixed wrong readlink() usage (lstat() doesn't report dest link size!).
Thanks to Henk Boom for pointing this out.
--- a/src/platform_unix.c Sun Jun 21 17:37:47 2009 -0400
+++ b/src/platform_unix.c Wed Jul 08 17:46:48 2009 -0400
@@ -198,12 +198,42 @@
} /* findBinaryInPath */
+static char *readSymLink(const char *path)
+{
+ ssize_t len = 64;
+ ssize_t rc = -1;
+ char *retval = NULL;
+
+ while (1)
+ {
+ char *ptr = (char *) allocator.Realloc(retval, (size_t) len);
+ if (ptr == NULL)
+ break; /* out of memory. */
+ retval = ptr;
+
+ rc = readlink(path, retval, len);
+ if (rc == -1)
+ break; /* not a symlink, i/o error, etc. */
+
+ else if (rc < len)
+ {
+ retval[rc] = '\0'; /* readlink doesn't null-terminate. */
+ return retval; /* we're good to go. */
+ } /* else if */
+
+ len *= 2; /* grow buffer, try again. */
+ } /* while */
+
+ if (retval != NULL)
+ allocator.Free(retval);
+ return NULL;
+} /* readSymLink */
+
+
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
{
- const char *PROC_SELF_EXE = "/proc/self/exe";
char *retval = NULL;
char *envr = NULL;
- struct stat stbuf;
/* fast path: default behaviour can handle this. */
if ( (argv0 != NULL) && (strchr(argv0, '/') != NULL) )
@@ -214,20 +244,12 @@
* /proc filesystem, you can get the full path to the current process from
* the /proc/self/exe symlink.
*/
- if ((lstat(PROC_SELF_EXE, &stbuf) != -1) && (S_ISLNK(stbuf.st_mode)))
+ retval = readSymLink("/proc/self/exe");
+ if (retval != NULL) /* chop off filename. */
{
- const size_t len = stbuf.st_size;
- char *buf = (char *) allocator.Malloc(len+1);
- if (buf != NULL) /* if NULL, maybe you'll get lucky later. */
- {
- if (readlink(PROC_SELF_EXE, buf, len) != len)
- allocator.Free(buf);
- else
- {
- buf[len] = '\0'; /* readlink doesn't null-terminate. */
- retval = buf; /* we're good to go. */
- } /* else */
- } /* if */
+ char *ptr = strrchr(retval, '/');
+ if (ptr != NULL)
+ *ptr = '\0';
} /* if */
if ((retval == NULL) && (argv0 != NULL))