mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 13:39:02 +00:00
fish handling of readlink()
The readlink() function does not null terminate the path it returns.
Remove the OS X code that deals with a path buffer that is too short. For
one thing a loop isn't needed since we're told how big of a buffer
is required if the first _NSGetExecutablePath() call fails. But more
important it is so unlikely that the path will be longer than PATH_MAX
that if it is we should just give up.
Fixes 2931.
(cherry picked from commit 8e103c231e
)
This commit is contained in:
parent
c2e9cda7b3
commit
baee807837
1 changed files with 22 additions and 27 deletions
45
src/fish.cpp
45
src/fish.cpp
|
@ -92,39 +92,34 @@ extern "C" {
|
||||||
int _NSGetExecutablePath(char* buf, uint32_t* bufsize);
|
int _NSGetExecutablePath(char* buf, uint32_t* bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the path to the current executable. This needs to be realpath'd. */
|
// Return the path to the current executable. This needs to be realpath'd.
|
||||||
static std::string get_executable_path(const char *argv0)
|
static std::string get_executable_path(const char *argv0)
|
||||||
{
|
{
|
||||||
char buff[PATH_MAX];
|
char buff[PATH_MAX + 1];
|
||||||
|
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
{
|
// On OS X use it's proprietary API to get the path to the executable.
|
||||||
/* Returns 0 on success, -1 if the buffer is too small */
|
|
||||||
uint32_t buffSize = sizeof buff;
|
uint32_t buffSize = sizeof buff;
|
||||||
if (0 == _NSGetExecutablePath(buff, &buffSize))
|
if (_NSGetExecutablePath(buff, &buffSize) == 0) return std::string(buff);
|
||||||
|
#else
|
||||||
|
// On non-OS X UNIXes, try /proc directory.
|
||||||
|
ssize_t len;
|
||||||
|
len = readlink("/proc/self/exe", buff, sizeof buff); // Linux
|
||||||
|
if (len == -1) {
|
||||||
|
len = readlink("/proc/curproc/file", buff, sizeof buff); // BSD
|
||||||
|
if (len == -1) {
|
||||||
|
len = readlink("/proc/self/path/a.out", buff, sizeof buff); // Solaris
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (len > 0) {
|
||||||
|
buff[len] = '\0';
|
||||||
return std::string(buff);
|
return std::string(buff);
|
||||||
|
|
||||||
/* Loop until we're big enough */
|
|
||||||
char *mbuff = (char *)malloc(buffSize);
|
|
||||||
while (0 > _NSGetExecutablePath(mbuff, &buffSize))
|
|
||||||
mbuff = (char *)realloc(mbuff, buffSize);
|
|
||||||
|
|
||||||
/* Return the string */
|
|
||||||
std::string result = mbuff;
|
|
||||||
free(mbuff);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
/* On other Unixes, try /proc directory. This might be worth breaking out into macros. */
|
|
||||||
if (0 < readlink("/proc/self/exe", buff, sizeof buff) || // Linux
|
|
||||||
0 < readlink("/proc/curproc/file", buff, sizeof buff) || // BSD
|
|
||||||
0 < readlink("/proc/self/path/a.out", buff, sizeof buff)) // Solaris
|
|
||||||
{
|
|
||||||
return std::string(buff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Just return argv0, which probably won't work (i.e. it's not an absolute path or a path relative to the working directory, but instead something the caller found via $PATH). We'll eventually fall back to the compile time paths. */
|
// Just return argv0, which probably won't work (i.e. it's not an absolute path or a path
|
||||||
|
// relative to the working directory, but instead something the caller found via $PATH). We'll
|
||||||
|
// eventually fall back to the compile time paths.
|
||||||
return std::string(argv0 ? argv0 : "");
|
return std::string(argv0 ? argv0 : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue