Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fixed wrong readlink() usage (lstat() doesn't report dest link size!).
Thanks to Henk Boom for pointing this out.
  • Loading branch information
icculus committed Jul 8, 2009
1 parent 71fc15f commit ff80fc8
Showing 1 changed file with 37 additions and 15 deletions.
52 changes: 37 additions & 15 deletions src/platform_unix.c
Expand Up @@ -198,12 +198,42 @@ static char *findBinaryInPath(const char *bin, char *envr)
} /* 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) )
Expand All @@ -214,20 +244,12 @@ char *__PHYSFS_platformCalcBaseDir(const char *argv0)
* /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))
Expand Down

0 comments on commit ff80fc8

Please sign in to comment.