此代码或多或少可以满足您的需求。它使用我在 GitHub 上的 SOQ(堆栈溢出问题)存储库中提供的错误报告代码,作为 src/libsoq 子目录中的文件 stderr.c 和 stderr.h。
#include "stderr.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
enum { NUM_CHILDREN = 5 };
enum { MSG_BUFFSIZE = 64 };
static void be_childish(int kid, int *fd);
int main(int argc, char **argv)
{
int fd[2 * NUM_CHILDREN];
int pid[NUM_CHILDREN];
err_setarg0(argv[0]);
err_setlogopts(ERR_PID);
if (argc != 1)
err_usage("");
for (int i = 0; i < NUM_CHILDREN; i++)
{
if (pipe(&fd[2 * i]) != 0)
err_syserr("failed to create pipe for child %d: ", i);
}
for (int i = 0; i < NUM_CHILDREN; i++)
{
if ((pid[i] = fork()) < 0)
err_syserr("failed to fork child %d: ", i);
else if (pid[i] == 0)
be_childish(i, fd);
else
{
printf("Child %d has PID %d\n", i, pid[i]);
fflush(stdout);
}
}
char buffer[MSG_BUFFSIZE];
for (int i = 0; i < NUM_CHILDREN; i++)
{
close(fd[2 * i + 1]);
int pipe_in = fd[2 * i + 0];
int nbytes = read(pipe_in, buffer, sizeof(buffer));
if (nbytes < 0)
err_syserr("failed to read from FD %2d: ", pipe_in);
printf("Got %2d bytes [%.*s] from FD %2d, PID %d\n",
nbytes, nbytes, buffer, pipe_in, pid[i]);
close(pipe_in);
}
for (int i = 0; i < NUM_CHILDREN; i++)
{
int status;
int corpse = wait(&status);
if (corpse > 0)
printf("Child with PID %d exited with status 0x%.4X\n", corpse, status);
else
err_syserr("Failed to wait for dead children: ");
}
return 0;
}
static void be_childish(int kid, int *fd)
{
for (int i = 0; i < kid; i++)
{
close(fd[2 * i + 0]);
close(fd[2 * i + 1]);
}
close(fd[2 * kid + 0]);
int estat = kid + 32;
char buffer[MSG_BUFFSIZE];
int nbytes = snprintf(buffer, sizeof(buffer),
"Child %d (PID %d) exiting with status %d",
kid, (int)getpid(), estat);
int pipe_out = fd[2 * kid + 1];
if (write(pipe_out, buffer, nbytes) != nbytes)
err_syserr("failed to write to parent: ");
close(pipe_out);
exit(estat);
}
示例运行:
Child 0 has PID 36957
Child 1 has PID 36958
Child 2 has PID 36959
Child 3 has PID 36960
Child 4 has PID 36961
Got 42 bytes [Child 0 (PID 36957) exiting with status 32] from FD 3, PID 36957
Got 42 bytes [Child 1 (PID 36958) exiting with status 33] from FD 5, PID 36958
Got 42 bytes [Child 2 (PID 36959) exiting with status 34] from FD 7, PID 36959
Got 42 bytes [Child 3 (PID 36960) exiting with status 35] from FD 9, PID 36960
Got 42 bytes [Child 4 (PID 36961) exiting with status 36] from FD 11, PID 36961
Child with PID 36960 exited with status 0x2300
Child with PID 36959 exited with status 0x2200
Child with PID 36958 exited with status 0x2100
Child with PID 36957 exited with status 0x2000
Child with PID 36961 exited with status 0x2400