Этот код более или менее делает то, что вы хотите.Он использует код сообщения об ошибках, который доступен в моем SOQ (вопросы о переполнении стека) на GitHub в виде файлов stderr.c
и stderr.h
в подкаталоге src / libsoq .
#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