Reputation: 45
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
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