mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2025-12-20 05:20:05 +01:00
proc-utils: Make sure '/proc/<pid>/*' files exist before opening them
This avoids warnings if the specific file does not exist, especially when the process has being removed quickly. Fixes #816
This commit is contained in:
parent
5c6a72e3cf
commit
f8be5a76e6
1 changed files with 49 additions and 37 deletions
|
|
@ -6,7 +6,9 @@
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <spa/utils/cleanup.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "proc-utils.h"
|
#include "proc-utils.h"
|
||||||
|
|
@ -145,6 +147,21 @@ wp_proc_info_get_cgroup (WpProcInfo * self)
|
||||||
return self->cgroup;
|
return self->cgroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FILE *
|
||||||
|
fdopenat (int dirfd, const char *path, int flags, const char *mode, mode_t perm)
|
||||||
|
{
|
||||||
|
int fd = openat (dirfd, path, flags, perm);
|
||||||
|
if (fd >= 0) {
|
||||||
|
FILE *f = fdopen (fd, mode);
|
||||||
|
if (f)
|
||||||
|
return f;
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets the process information of a given PID
|
* \brief Gets the process information of a given PID
|
||||||
* \ingroup wpprocutils
|
* \ingroup wpprocutils
|
||||||
|
|
@ -155,51 +172,46 @@ WpProcInfo *
|
||||||
wp_proc_utils_get_proc_info (pid_t pid)
|
wp_proc_utils_get_proc_info (pid_t pid)
|
||||||
{
|
{
|
||||||
WpProcInfo *ret = wp_proc_info_new (pid);
|
WpProcInfo *ret = wp_proc_info_new (pid);
|
||||||
g_autofree gchar *status = NULL;
|
char path [64];
|
||||||
g_autoptr (GError) error = NULL;
|
spa_autoclose int base_fd = -1;
|
||||||
gsize length = 0;
|
FILE *file;
|
||||||
|
g_autofree gchar *line = NULL;
|
||||||
|
size_t size = 0;
|
||||||
|
|
||||||
|
snprintf (path, sizeof(path), "/proc/%d", pid);
|
||||||
|
base_fd = open (path,
|
||||||
|
O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY, 0);
|
||||||
|
if (base_fd < 0) {
|
||||||
|
wp_info ("Could not open process info directory %s, skipping", path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get parent PID */
|
/* Get parent PID */
|
||||||
{
|
file = fdopenat (base_fd, "status",
|
||||||
g_autofree gchar *path = g_strdup_printf ("/proc/%d/status", pid);
|
O_RDONLY | O_NONBLOCK | O_CLOEXEC | O_NOCTTY, "r", 0);
|
||||||
if (g_file_get_contents (path, &status, &length, &error)) {
|
if (file) {
|
||||||
const gchar *loc = strstr (status, "\nPPid:");
|
while (getline (&line, &size, file) > 1)
|
||||||
if (loc) {
|
if (sscanf (line, "PPid:%d\n", &ret->parent) == 1)
|
||||||
const gint res = sscanf (loc, "\nPPid:%d\n", &ret->parent);
|
break;
|
||||||
if (!res || res == EOF)
|
fclose (file);
|
||||||
wp_warning ("failed to parse status PPID for PID %d", pid);
|
|
||||||
} else {
|
|
||||||
wp_warning ("failed to find status parent PID for PID %d", pid);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
wp_warning ("failed to get status for PID %d: %s", pid, error->message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get cgroup */
|
/* Get cgroup */
|
||||||
{
|
file = fdopenat (base_fd, "cgroup",
|
||||||
g_autofree gchar *path = g_strdup_printf ("/proc/%d/cgroup", pid);
|
O_RDONLY | O_NONBLOCK | O_CLOEXEC | O_NOCTTY, "r", 0);
|
||||||
if (g_file_get_contents (path, &ret->cgroup, &length, &error)) {
|
if (file) {
|
||||||
if (length > 0)
|
if (getline (&line, &size, file) > 1)
|
||||||
ret->cgroup [length - 1] = '\0'; /* Remove EOF character */
|
ret->cgroup = g_strstrip (g_strdup (line));
|
||||||
} else {
|
fclose (file);
|
||||||
wp_warning ("failed to get cgroup for PID %d: %s", pid, error->message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get args */
|
/* Get args */
|
||||||
{
|
file = fdopenat (base_fd, "cmdline",
|
||||||
g_autofree gchar *path = g_strdup_printf ("/proc/%d/cmdline", pid);
|
O_RDONLY | O_NONBLOCK | O_CLOEXEC | O_NOCTTY, "r", 0);
|
||||||
FILE *file = fopen (path, "rb");
|
if (file) {
|
||||||
if (file) {
|
while (getdelim (&line, &size, 0, file) > 1 && ret->n_args < MAX_ARGS)
|
||||||
g_autofree gchar *lineptr = NULL;
|
ret->args[ret->n_args++] = g_strdup (line);
|
||||||
size_t size = 0;
|
fclose (file);
|
||||||
while (getdelim (&lineptr, &size, 0, file) > 1 && ret->n_args < MAX_ARGS)
|
|
||||||
ret->args[ret->n_args++] = g_strdup (lineptr);
|
|
||||||
fclose (file);
|
|
||||||
} else {
|
|
||||||
wp_warning ("failed to get cmdline for PID %d: %m", pid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue