mirror of
https://github.com/containers/podman.git
synced 2025-05-19 16:18:51 +08:00

This should never be pulled into the remote client. Signed-off-by: Paul Holzinger <pholzing@redhat.com>
85 lines
1.8 KiB
C
85 lines
1.8 KiB
C
//go:build !remote
|
|
// +build !remote
|
|
|
|
#define _GNU_SOURCE
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/mount.h>
|
|
#include <sys/wait.h>
|
|
#include <unistd.h>
|
|
|
|
/* keep special_exit_code in sync with container_top_linux.go */
|
|
int special_exit_code = 255;
|
|
char **argv = NULL;
|
|
|
|
void
|
|
create_argv (int len)
|
|
{
|
|
/* allocate one extra element because we need a final NULL in c */
|
|
argv = malloc (sizeof (char *) * (len + 1));
|
|
if (argv == NULL)
|
|
{
|
|
fprintf (stderr, "failed to allocate ps argv");
|
|
exit (special_exit_code);
|
|
}
|
|
/* add final NULL */
|
|
argv[len] = NULL;
|
|
}
|
|
|
|
void
|
|
set_argv (int pos, char *arg)
|
|
{
|
|
argv[pos] = arg;
|
|
}
|
|
|
|
/*
|
|
We use cgo code here so we can fork then exec separately,
|
|
this is done so we can mount proc after the fork because the pid namespace is
|
|
only active after spawning children.
|
|
*/
|
|
void
|
|
fork_exec_ps ()
|
|
{
|
|
int r, status = 0;
|
|
pid_t pid;
|
|
|
|
if (argv == NULL)
|
|
{
|
|
fprintf (stderr, "argv not initialized");
|
|
exit (special_exit_code);
|
|
}
|
|
|
|
pid = fork ();
|
|
if (pid < 0)
|
|
{
|
|
fprintf (stderr, "fork: %m");
|
|
exit (special_exit_code);
|
|
}
|
|
if (pid == 0)
|
|
{
|
|
r = mount ("proc", "/proc", "proc", 0, NULL);
|
|
if (r < 0)
|
|
{
|
|
fprintf (stderr, "mount proc: %m");
|
|
exit (special_exit_code);
|
|
}
|
|
/* use execve to unset all env vars, we do not want to leak anything into the container */
|
|
execve (argv[0], argv, NULL);
|
|
fprintf (stderr, "execve: %m");
|
|
exit (special_exit_code);
|
|
}
|
|
|
|
r = waitpid (pid, &status, 0);
|
|
if (r < 0)
|
|
{
|
|
fprintf (stderr, "waitpid: %m");
|
|
exit (special_exit_code);
|
|
}
|
|
if (WIFEXITED (status))
|
|
exit (WEXITSTATUS (status));
|
|
if (WIFSIGNALED (status))
|
|
exit (128 + WTERMSIG (status));
|
|
exit (special_exit_code);
|
|
}
|