Skip to content

Commit

Permalink
util/proc: add helper to resolve a pid file descriptor
Browse files Browse the repository at this point in the history
A pid FD can be resolved by reading from proc's fdinfo

Signed-off-by: Luca Boccassi <[email protected]>
(rework based on the new proc helpers)
Signed-off-by: David Rheinsberg <[email protected]>
  • Loading branch information
bluca authored and dvdhrm committed Jul 6, 2023
1 parent bbcf781 commit 156e16c
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/util/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@
#include <unistd.h>
#include "util/error.h"
#include "util/proc.h"
#include "util/string.h"

/*
* A file in /proc can be at most 4M minus one. If required, we start with a 4K
* read, then try a 4M one if that fails. In the vast majority of cases, 4K
* will be enough.
*/
#define PROC_SIZE_MIN (4U*1024U)
#define PROC_SIZE_MAX (4U*1024U*1024U - 1U)

/**
* proc_field() - Extract individual field from proc-text-file
Expand Down Expand Up @@ -176,3 +185,29 @@ int proc_get_seclabel(pid_t pid, char **labelp, size_t *n_labelp) {
*labelp = label;
return 0;
}

int proc_resolve_pidfd(int pidfd, pid_t *pidp) {
_c_cleanup_(c_freep) char *data = NULL, *field = NULL;
_c_cleanup_(c_closep) int fd = -1;
char path[64];
int r;

sprintf(path, "/proc/self/fdinfo/%d", pidfd);
fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0)
return error_origin(-errno);

r = proc_read(fd, &data, NULL);
if (r)
return error_fold(r);

r = proc_field(data, "Pid", &field);
if (r)
return error_fold(r);

r = util_strtoint(pidp, field);
if (r)
return error_fold(r);

return 0;
}
1 change: 1 addition & 0 deletions src/util/proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ int proc_field(const char *data, const char *key, char **valuep);
int proc_read(int fd, char **datap, size_t *n_datap);

int proc_get_seclabel(pid_t pid, char **labelp, size_t *n_labelp);
int proc_resolve_pidfd(int pidfd, pid_t *pidp);
19 changes: 19 additions & 0 deletions src/util/test-proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,27 @@ static void test_read(void) {
c_free(data);
}

static void test_resolve_pidfd(void) {
_c_cleanup_(c_closep) int pidfd = -1;
pid_t pid;
int r;

pidfd = syscall_pidfd_open(getpid(), 0);
if (pidfd < 0) {
c_assert(errno == ENOSYS);
return;
}

c_assert(pidfd >= 0);

r = proc_resolve_pidfd(pidfd, &pid);
c_assert(!r);
c_assert(pid == getpid());
}

int main(int argc, char **argv) {
test_field();
test_read();
test_resolve_pidfd();
return 0;
}

0 comments on commit 156e16c

Please sign in to comment.