Follow symbolic links when searching for executable directory

This commit is contained in:
Colin Wallace
2015-08-23 01:02:40 -07:00
parent 0075192ada
commit cd40b0aefb
+40 -7
View File
@@ -172,6 +172,42 @@ public:
}; };
static RageFileDriverMountpoints *g_Mountpoints = NULL; static RageFileDriverMountpoints *g_Mountpoints = NULL;
static RString ExtractDirectory( RString sPath )
{
// return the directory containing sPath
size_t n = sPath.find_last_of("/");
if( n != sPath.npos )
sPath.erase(n);
else
sPath.erase();
return sPath;
}
static RString ReadlinkRecursive( RString sPath )
{
#if defined(UNIX) || defined(MACOSX)
// unices support symbolic links; dereference them
RString dereferenced = sPath;
do
{
sPath = dereferenced;
char derefPath[512];
ssize_t linkSize = readlink(sPath, derefPath, sizeof(derefPath));
if ( linkSize != -1 && linkSize != sizeof(derefPath) )
{
dereferenced = RString( derefPath, linkSize );
if (derefPath[0] != '/')
{
// relative link
dereferenced = RString( ExtractDirectory(sPath) + "/" + dereferenced);
}
}
} while (sPath != dereferenced);
#endif
return sPath;
}
static RString GetDirOfExecutable( RString argv0 ) static RString GetDirOfExecutable( RString argv0 )
{ {
// argv[0] can be wrong in most OS's; try to avoid using it. // argv[0] can be wrong in most OS's; try to avoid using it.
@@ -196,11 +232,7 @@ static RString GetDirOfExecutable( RString argv0 )
#endif #endif
// strip off executable name // strip off executable name
size_t n = sPath.find_last_of("/"); sPath = ExtractDirectory(sPath);
if( n != sPath.npos )
sPath.erase(n);
else
sPath.erase();
if( !bIsAbsolutePath ) if( !bIsAbsolutePath )
{ {
@@ -219,17 +251,18 @@ static RString GetDirOfExecutable( RString argv0 )
{ {
if( access(*i + "/" + argv0, X_OK|R_OK) ) if( access(*i + "/" + argv0, X_OK|R_OK) )
continue; continue;
sPath = *i; sPath = ExtractDirectory(ReadlinkRecursive(*i + "/" + argv0));
break; break;
} }
if( sPath.empty() ) if( sPath.empty() )
sPath = GetCwd(); // What? sPath = GetCwd(); // What?
else if( sPath[0] != '/' ) // For example, if . is in $PATH. else if( sPath[0] != '/' ) // For example, if . is in $PATH.
sPath = GetCwd() + "/" + sPath; sPath = GetCwd() + "/" + sPath;
} }
else else
{ {
sPath = GetCwd() + "/" + sPath; sPath = ExtractDirectory(ReadlinkRecursive(GetCwd() + "/" + argv0));
} }
#else #else
sPath = GetCwd() + "/" + sPath; sPath = GetCwd() + "/" + sPath;