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)
|
||||
/* search for the full path of the binary using the argv[0] parameter
|
||||
** 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
|
||||
** gratuitous path components such as "./" or ".." removed.
|
||||
**
|
||||
** the binary name will be passed to realpath(3p) to have all symlinks
|
||||
** resolved and gratuitous path components like "../" removed.
|
||||
**
|
||||
** argument "pathbuf" is a work buffer of size PATH_MAX,
|
||||
** "a0" the original argv[0].
|
||||
** returns pathbuf with the full path of the binary, minus the binary
|
||||
** name itself.
|
||||
** returns pathbuf with the full path of the binary.
|
||||
*/
|
||||
{
|
||||
if (a0[0] == '/') {
|
||||
strcpy (pathbuf, a0);
|
||||
} else if (a0[0] == '.' || strrchr (a0, '/')) {
|
||||
/* realpath returns the work buffer passed to it, so checking the
|
||||
return value is superfluous. gcc11 warns anyway. */
|
||||
if (realpath (a0, pathbuf)) {}
|
||||
} else {
|
||||
SearchPathBin (a0, pathbuf, PATH_MAX);
|
||||
char tmp[PATH_MAX];
|
||||
|
||||
if (!strchr(a0, '/')) {
|
||||
/* path doesn't contain directory separator, so it was looked up
|
||||
via PATH environment variable */
|
||||
SearchPathBin (a0, tmp, PATH_MAX);
|
||||
a0 = tmp;
|
||||
}
|
||||
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
|
||||
@ -289,32 +277,19 @@ void AddSubSearchPathFromBin (SearchPaths* P, const char* SubDir)
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
GetProgPath(Dir, ArgVec[0]);
|
||||
|
||||
#endif
|
||||
|
||||
/* Remove binary name */
|
||||
Ptr = strrchr (Dir, '\\');
|
||||
Ptr = strrchr (Dir, PATHSEP[0]);
|
||||
if (Ptr == 0) {
|
||||
return;
|
||||
}
|
||||
*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 */
|
||||
Ptr = strrchr (Dir, PATHSEP[0]);
|
||||
if (Ptr == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user