Rob
Rob

Reputation: 45

How to view /proc/ information of a child proccess?

Specifically, I want to view the /proc/PID/io file for a child process created by fork(). I can only think to try to access it within the parent process, but it is always inaccessible.

pid_t pid = fork();
if (pid < 0) // failed
{
    return;
}
else if (pid == 0) // child process
{
    char* args[] = { "cat", "test.txt" };
    execv(args[0], args);
}
else // parent process
{
    wait(NULL);
}

The file is accessible before the call to wait, but it of course doesn't contain any nonzero values since the child hasn't finished yet. The file is inaccessible after the call to wait, because the child has terminated. So, how would I go about this?

Admittedly, this is for a project, but we have not covered anything beyond basic forking. Any help is appreciated.

Upvotes: 1

Views: 348

Answers (1)

Sergey L.
Sergey L.

Reputation: 22542

When your child terminates you receive a signal SIGCHLD. Calling wait will wait for this and then clean up the child.

What you have to do is install a signal handler for SIGCHLD, when it arrives the child process is already a zombie, but its /proc entry still exists. Then read /proc/[child pid]/io and only afterwards wait for the child in order to clean it up.

Edit:

Here is some code (requires root (sudo) permissions:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>

pthread_mutex_t mutex;

void sigchldhandler(int s) {
    // signals to the main thread that child has exited
    pthread_mutex_unlock(&mutex); 
}

int main() {

    // init and lock the mutex
    pthread_mutex_init(&mutex, NULL);
    pthread_mutex_lock(&mutex);

    // install signal handler
    signal(SIGCHLD, sigchldhandler);

    pid_t child_pid = fork();

    if (child_pid > 0) {
        // parent
        // wait for the signal
        pthread_mutex_lock(&mutex);

        char buffer[0x1000];
        sprintf(buffer, "/proc/%d/io", child_pid);
        FILE * fp = fopen(buffer, "r");
        if (!fp) {
            perror("fopen");
            abort();
        }
        while (fgets(buffer, sizeof(buffer), fp)) {
            printf("%s", buffer);
        }
        // clean up child
        wait(0);

        return 0;

    } else if (child_pid < 0) {
        perror("fork");
        abort();
    } else {
        // child
        char* args[] = { "cat", "test.txt" };
        execv(args[0], args);
    }

}

Upvotes: 2

Related Questions