Skip to content

Commit

Permalink
Linux: support openat() without readlinkat()
Browse files Browse the repository at this point in the history
    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
  • Loading branch information
cgzones authored and BenBE committed Aug 9, 2022
1 parent 8e19b2a commit 2f62ee0
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 6 deletions.
37 changes: 37 additions & 0 deletions Compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@ 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

#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,
Expand Down Expand Up @@ -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);
}
5 changes: 5 additions & 0 deletions Compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
8 changes: 2 additions & 6 deletions linux/LinuxProcessList.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 2f62ee0

Please sign in to comment.