mirror of
https://github.com/cc65/cc65.git
synced 2024-12-24 11:31:31 +00:00
change GetProgPath() to return full & resolved binary path
GetProgPath() now resolves the path derived from argv[0] always via realpath(3p) to its real location in the filesystem, and returns the path including binary name, effectively making it work like windows' GetModuleFileName(), so we can re-use the existing code to strip the trailing binary name. since symlinks are now always resolved, we no longer need the special case code for linux to use /proc/self/exe for this purpose.
This commit is contained in:
parent
546e82965d
commit
5867d3a020
@ -232,44 +232,32 @@ static int SearchPathBin(const char* bin, char* buf, size_t buflen)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static char* MyDirname(char* in)
|
|
||||||
/* returns the dirname() part of a filename.
|
|
||||||
** the passed string is modified in place, then returned.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
char* p = strrchr (in, '/');
|
|
||||||
|
|
||||||
if (p) {
|
|
||||||
*p = 0;
|
|
||||||
}
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static char* GetProgPath(char* pathbuf, char* a0)
|
static char* GetProgPath(char* pathbuf, char* a0)
|
||||||
/* search for the full path of the binary using the argv[0] parameter
|
/* search for the full path of the binary using the argv[0] parameter
|
||||||
** passed to int main(), according to the description above.
|
** passed to int main(), according to the description above.
|
||||||
** if the binary was started using a relative path, realpath(3p) will
|
**
|
||||||
** turn the relative path into an absolute path with pwd resolved, and
|
** the binary name will be passed to realpath(3p) to have all symlinks
|
||||||
** gratuitous path components such as "./" or ".." removed.
|
** resolved and gratuitous path components like "../" removed.
|
||||||
**
|
**
|
||||||
** argument "pathbuf" is a work buffer of size PATH_MAX,
|
** argument "pathbuf" is a work buffer of size PATH_MAX,
|
||||||
** "a0" the original argv[0].
|
** "a0" the original argv[0].
|
||||||
** returns pathbuf with the full path of the binary, minus the binary
|
** returns pathbuf with the full path of the binary.
|
||||||
** name itself.
|
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if (a0[0] == '/') {
|
char tmp[PATH_MAX];
|
||||||
strcpy (pathbuf, a0);
|
|
||||||
} else if (a0[0] == '.' || strrchr (a0, '/')) {
|
if (!strchr(a0, '/')) {
|
||||||
/* realpath returns the work buffer passed to it, so checking the
|
/* path doesn't contain directory separator, so it was looked up
|
||||||
return value is superfluous. gcc11 warns anyway. */
|
via PATH environment variable */
|
||||||
if (realpath (a0, pathbuf)) {}
|
SearchPathBin (a0, tmp, PATH_MAX);
|
||||||
} else {
|
a0 = tmp;
|
||||||
SearchPathBin (a0, pathbuf, PATH_MAX);
|
|
||||||
}
|
}
|
||||||
return MyDirname(pathbuf);
|
|
||||||
|
/* realpath returns the work buffer passed to it, so checking the
|
||||||
|
return value is superfluous. gcc11 warns anyway. */
|
||||||
|
if (realpath (a0, pathbuf)) {}
|
||||||
|
|
||||||
|
return pathbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -289,32 +277,19 @@ void AddSubSearchPathFromBin (SearchPaths* P, const char* SubDir)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
GetProgPath(Dir, ArgVec[0]);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Remove binary name */
|
/* Remove binary name */
|
||||||
Ptr = strrchr (Dir, '\\');
|
Ptr = strrchr (Dir, PATHSEP[0]);
|
||||||
if (Ptr == 0) {
|
if (Ptr == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*Ptr = '\0';
|
*Ptr = '\0';
|
||||||
|
|
||||||
#elif defined(__linux__)
|
|
||||||
|
|
||||||
/* reading from proc will return the real location, excluding symlinked
|
|
||||||
pathes - which is needed for certain edgy cases */
|
|
||||||
if (readlink("/proc/self/exe", Dir, sizeof(Dir) - 1) < 0) {
|
|
||||||
GetProgPath(Dir, ArgVec[0]);
|
|
||||||
} else {
|
|
||||||
/* Remove binary name */
|
|
||||||
Ptr = strrchr (Dir, PATHSEP[0]);
|
|
||||||
if (Ptr == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*Ptr = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
GetProgPath(Dir, ArgVec[0]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check for 'bin' directory */
|
/* Check for 'bin' directory */
|
||||||
Ptr = strrchr (Dir, PATHSEP[0]);
|
Ptr = strrchr (Dir, PATHSEP[0]);
|
||||||
if (Ptr == 0) {
|
if (Ptr == 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user