diff options
author | Christian Göttsche <cgzones@googlemail.com> | 2022-08-09 20:59:10 +0200 |
---|---|---|
committer | BenBE <BenBE@geshi.org> | 2022-08-09 22:15:19 +0200 |
commit | 2f62ee0698792c06ee698475049c8d8f03e0e73c (patch) | |
tree | 4d74f7f29d9c624f9e282da03ea78ae29e7b68a4 | |
parent | 8e19b2a2c5655c132a3b41f9a911471dd32914d4 (diff) |
Linux: support openat() without readlinkat()
linux/LinuxProcessList.c:1094:52: error: format specifies type 'char *' but the argument has type 'openat_arg_t' (aka 'int') [-Werror,-Wformat]
xSnprintf(filename, sizeof(filename), "%s/cwd", procFd);
~~ ^~~~~~
%d
linux/LinuxProcessList.c:1333:44: error: format specifies type 'char *' but the argument has type 'openat_arg_t' (aka 'int') [-Werror,-Wformat]
xSnprintf(path, sizeof(path), "%s/exe", procFd);
~~ ^~~~~~
%d
Supersedes: #1025
-rw-r--r-- | Compat.c | 37 | ||||
-rw-r--r-- | Compat.h | 5 | ||||
-rw-r--r-- | linux/LinuxProcessList.c | 8 |
3 files changed, 44 insertions, 6 deletions
@@ -11,6 +11,7 @@ in the source distribution for its full text. #include <errno.h> #include <fcntl.h> // IWYU pragma: keep +#include <limits.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> // IWYU pragma: keep @@ -18,6 +19,12 @@ in the source distribution for its full text. #include "XUtils.h" // IWYU pragma: keep +/* GNU/Hurd does not have PATH_MAX in limits.h */ +#ifndef PATH_MAX +# define PATH_MAX 4096 +#endif + + int Compat_faccessat(int dirfd, const char* pathname, int mode, @@ -117,3 +124,33 @@ ssize_t Compat_readlinkat(int dirfd, #endif } + +ssize_t Compat_readlink(openat_arg_t dirfd, + const char* pathname, + char* buf, + size_t bufsize) { + +#ifdef HAVE_OPENAT + + char fdPath[32]; + xSnprintf(fdPath, sizeof(fdPath), "/proc/self/fd/%d", dirfd); + + char dirPath[PATH_MAX + 1]; + ssize_t r = readlink(fdPath, dirPath, sizeof(dirPath) - 1); + if (r < 0) + return r; + + dirPath[r] = '\0'; + + char linkPath[PATH_MAX + 1]; + xSnprintf(linkPath, sizeof(linkPath), "%s/%s", dirPath, pathname); + +#else + + char linkPath[PATH_MAX + 1]; + xSnprintf(linkPath, sizeof(linkPath), "%s/%s", dirfd, pathname); + +#endif /* HAVE_OPENAT */ + + return readlink(linkPath, buf, bufsize); +} @@ -56,4 +56,9 @@ ssize_t Compat_readlinkat(int dirfd, char* buf, size_t bufsize); +ssize_t Compat_readlink(openat_arg_t dirfd, + const char* pathname, + char* buf, + size_t bufsize); + #endif /* HEADER_Compat */ diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 45b045c8..0ed2e4f7 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -1090,9 +1090,7 @@ static void LinuxProcessList_readCwd(LinuxProcess* process, openat_arg_t procFd) #if defined(HAVE_READLINKAT) && defined(HAVE_OPENAT) ssize_t r = readlinkat(procFd, "cwd", pathBuffer, sizeof(pathBuffer) - 1); #else - char filename[MAX_NAME + 1]; - xSnprintf(filename, sizeof(filename), "%s/cwd", procFd); - ssize_t r = readlink(filename, pathBuffer, sizeof(pathBuffer) - 1); + ssize_t r = Compat_readlink(procFd, "cwd", pathBuffer, sizeof(pathBuffer) - 1); #endif if (r < 0) { @@ -1329,9 +1327,7 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, openat_arg_t proc #if defined(HAVE_READLINKAT) && defined(HAVE_OPENAT) amtRead = readlinkat(procFd, "exe", filename, sizeof(filename) - 1); #else - char path[4096]; - xSnprintf(path, sizeof(path), "%s/exe", procFd); - amtRead = readlink(path, filename, sizeof(filename) - 1); + amtRead = Compat_readlink(procFd, "exe", filename, sizeof(filename) - 1); #endif if (amtRead > 0) { filename[amtRead] = 0; |