read() stdout from child in infinite loop - c

I am forking a child which will run an infinite loop and do some things. Text will be printed to stdout with printf when the child is in a 'ready' status. I am redirecting the child's stdout with a pipe so the parent can see it. When this text prints I would like the parent to be unblocked.
The problem seems to be that the read() call will stay blocked even after the printf() call.
Here is some sample code I am working with:
parent:
#include <stdio.h>
#include <unistd.h>
int main()
{
int fd[2];
pipe(fd);
char buffer[256];
switch(fork())
{
case -1:
printf("fork failed\n");
_exit(1);
case 0:
printf("Starting progtest...\n");
close(fd[0]);
dup2(fd[1], STDOUT_FILENO);
close(fd[1]);
execl("progtest", "progtest", NULL);
perror("exec failed");
_exit(1);
}
close(fd[1]);
read(fd[0], &buffer, sizeof(buffer));
close(fd[0]);
printf("buffer: %s\n", buffer);
}
child:
#include <stdio.h>
int main()
{
printf("ready\n");
while(1)
{
// stuff happens here
}
return 0;
}
I'm pretty sure the pipe is set up correctly. If I remove the infinite loop the parent will unblock and print "ready".
Is there any way I can use read() while the child is still running? Am I going about this incorrectly by using pipes? I need to do this twice with two different status messages.

It seems you are trying to perform inter process communication (IPC). There is no 1 to 1 communication syncronization with reads/write, the parent or child can write as much as they want to the file descriptor at once, and since they are running asynchronously you must ensure you are ready to deal with this.
Normally this is done by sending a header with each message that is a fixed size, containing the length of the payload. For example:
protocol header
#include <stdint.h>
struct Message
{
uint8_t length; // assuming a maximum message length of 255 bytes, adjust as needed.
};
You can define extra things here, usually it's a good idea to include the version, perhaps a sequence ID, etc. It is important that if you are communicating across a network, this header's size is absolute on all hardware implementations, so the use of stdint defines is required to ensure compatibility between architectures. It is also a good idea to ensure the endian is consistent if working across architectures also.
sending a message
const char data[] = "example";
// create a buffer large enough to pack the header and data into it
const uint8_t len = strlen(data) + 1;
char buffer[sizeof(struct Message) + len];
// populate the header
struct Message *m = (struct Message *)buffer;
m->length = len;
// copy in the payload after the header
memcpy(buffer + sizeof(struct Message), data, len);
// write the packed buffer
write(fd, buffer, sizeof(struct Message) + len);
reading a message
struct Message m;
if (read(fd, &m, sizeof(struct Message)) != sizeof(struct Message))
{
fprintf(stderr, "Failed to read the header\n");
exit(1);
}
// If required perform validation on the header here
ssize_t offset = 0;
char data[m.length];
while(offset < m.length)
{
ssize_t r = read(fd, data + offset, m.length - offset);
if (r < 0)
{
fprintf(stderr, "Read of message body failed\n");
exit(1);
}
if (r == 0)
{
fprintf(stderr, "The sender closed the connection\n");
exit(1);
}
offset += r;
}
printf("Message Length: %u, Message Data: %s\n", m.length, data);
The while loop to read is requires as the data may have been split up into chunks if the sender exceeded the write buffer and is now blocking waiting to write the remainder. The header can also be split across chunks and ideally should also be read using the same technique, but for brevity I have left this out.

Related

is it possible to read and write with the same file descriptor in C

I am trying to write to a file and display the output of the thing i wrote with another process. The code i come up with:
void readLine (int fd, char *str) {
int n;
do {
n = read (fd, str, 1);
} while (*str++ != '\0');
}
int main(int argc,char ** argv){
int fd=open("sharedFile",O_CREAT|O_RDWR|O_TRUNC,0600);
if(fork()==0){
char buf[1000];
while(1) {
readLine(fd,buf);
printf("%s\n",buf);
}
}else{
while(1){
sleep(1);
write(fd,"abcd",strlen("abcd")+1);
}
}
}
the output i want (each result spaced from the other with a period of one second):
abcd
abcd
abcd
....
Unfortunately this code doesn't work, it seems that the child process (the reader of the file "sharedFile") reads junk from the file because somehow it reads values even when the file is empty.
When trying to debug the code, readLine function never reads the written file correctly,it always reads 0 bytes.
Can someone help?
First of all, when a file descriptor becomes shared after forking, both the parent and child are pointing to the same open file description, which means in particular that they share the same file position. This is explained in the fork() man page.
So whenever the parent writes, the position is updated to the end of the file, and thus the child is always attempting to read at the end of the file, where there's no data. That's why read() returns 0, just as normal when you hit the end of a file.
(When this happens, you should not attempt to do anything with the data in the buffer. It's not that you're "reading junk", it's that you're not reading anything but are then pretending that whatever junk was in the buffer is what you just read. In particular your code utterly disregards the return value from read(), which is how you're supposed to tell what you actually read.)
If you want the child to have an independent file position, then the child needs to open() the file separately for itself and get a new fd pointing to a new file description.
But still, when the child has read all the data that's currently in the file, read() will again return 0; it won't wait around for the parent to write some more. The fact that some other process has a file open for writing don't affect the semantics of read() on a regular file.
So what you'll need to do instead is that when read() returns 0, you manually sleep for a while and then try again. When there's more data in the file, read() will return a positive number, and you can then process the data you read. Or, there are more elegant but more complicated approaches using system-specific APIs like Linux's inotify, which can sleep until a file's contents change. You may be familiar with tail -f, which uses some combination of these approaches on different systems.
Another dangerous bug is that if someone else writes text to the file that doesn't contain a null byte where expected, your child will read more data than the buffer can fit, thus overrunning it. This can be an exploitable security vulnerability.
Here is a version of the code that fixes these bugs and works for me:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void readLine (int fd, char *str, size_t max) {
size_t pos = 0;
while (pos < max) {
ssize_t n = read(fd, str + pos, 1);
if (n == 0) {
sleep(1);
} else if (n == 1) {
if (str[pos] == '\0') {
return;
}
pos++;
} else {
perror("read() failure");
exit(2);
}
}
fprintf(stderr, "Didn't receive null terminator in time\n");
exit(2);
}
int main(int argc, char ** argv){
int fd=open("sharedFile", O_CREAT|O_RDWR|O_TRUNC, 0600);
if (fd < 0) {
perror("parent opening sharedFile");
exit(2);
}
pid_t pid = fork();
if (pid == 0){
int newfd = open("sharedFile", O_RDONLY);
if (newfd < 0) {
perror("child opening sharedFile");
exit(2);
}
char buf[1000];
while (1) {
readLine(newfd, buf, 1000);
printf("%s\n",buf);
}
} else if (pid > 0) {
while (1){
sleep(1);
write(fd,"abcd",strlen("abcd")+1);
}
} else {
perror("fork");
exit(2);
}
return 0;
}

Q: Reading from pipe to screen

I'm trying to write a program that reads some text from a file and prints it to the screen. The parent will read the content of the file write it to n number of pipes and the children will read it and then print it.
So far this is what I've got:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
int main (void)
{
pid_t pid;
char c;
FILE *fd;
char buf[100];
int N_CHILDREN = 2;
int p[N_CHILDREN][2];
int i,j;
for(i=0; i<N_CHILDREN; i++)
{
pipe(p[i]);
}
fd=fopen("123.txt","r");
for(j=0; j < N_CHILDREN;j++)
{
pid = fork ();
if (pid == 0)
{
close (p[j][1]);
while(read(p[j][0], &fd,sizeof(buf)) > 0)
printf("\n%c",&fd);
}
if (pid < 0)
{
//Fork Failed
fprintf (stderr, "Fork failure.\n");
return EXIT_FAILURE;
}
if ( pid > 0) //Parent
{
close (p[j][0]);
write(p[j][1], fd ,sizeof(buf));
}
}
}
Problem is it's not really reading the content from the file. I've tried sending it a string of characters instead of reading from a file and it worked as intended, both children printed the message one time and the program ended.
Any thoughts about it? After reading the manuals I still can't see where the problem is.
You are confusing C Standard I/O streams (created with fopen(); written to with fprintf() et al., read with fscanf() et al.) with Unix file descriptor I/O (created with open() or pipe() et al., written to with write() et al., read with read() et al.)
Standard I/O functions take an opaque FILE * as a handle; Unix I/O functions take a file descriptor (a small int) as a handle.
Once you understand the conceptual difference, I'm sure you will realize that
FILE *fd = ...
read(..., &fd, ...);
is reading into a pointer-to-FILE -- not terribly useful :-)
Several problems here:
you make bad usage of read function by passing &fd, which is a FILE*. This function needs a pointer to the "buffer" to print, here I guess buf.
you don't check errors. For example if fopen fails.
you never read data from your file, so you have "nothing" to send to children.
you have to get returned value of read (in children) because it is the effective amount of data that you get. So it is the amount of data that you have to print after that (to stdout).
So here is an example code, see comments inside:
// put here all the needed includes (see manpages of functions)
// it is better to create a function for the child: the code
// is easier to read
// the child just get the file descriptor to read (the pipe)
void child(int fd) {
char buf[100]; // buffer to store data read
int ret; // the number of bytes that are read
// we read from 'fd', into 'buf'. It returns the number of bytes
// really read (could be smaller than size). Return <=0 when over
while((ret = read(fd, buf, sizeof(buf))) > 0) {
// write the 'ret' bytes to STDOUT (which as file descriptor 1)
write(1, buf, ret);
}
}
int main (void) {
pid_t pid;
char buf[100];
int N_CHILDREN = 2;
int p[N_CHILDREN][2];
int i,j, ret;
int fdi;
// create the pipes
for(i=0; i<N_CHILDREN; i++) {
if (pipe(p[i]) == -1) {
perror("pipe"); // ALWAYS check for errors
exit(1);
}
}
// open the file (with 'open' not 'fopen', more suitable for
// reading raw data
fdi = open("123.txt",O_RDONLY);
if (fdi < 0) {
perror("open"); // ALWAYS check for errors
exit(1);
}
// just spawn the children
for(j=0; j < N_CHILDREN;j++) {
pid = fork();
if (pid < 0) {
perror("fork"); // ALWAYS check for errors
exit(1);
}
if (pid == 0) { // child
close(p[j][1]); // close the writing part
child(p[j][0]); // call child function with corresp. FD
exit(0); // leave : the child should do nothing else
}
}
// don't need that part
for(j=0; j<N_CHILDREN; j++) {
close(p[j][0]); // close the read-part of pipes
}
// need to read file content, see comment in child() function
while ((ret = read(fdi, buf, sizeof(buf))) > 0) {
// write the data to all children
for(j=0; j<N_CHILDREN; j++) {
write(p[j][1], buf , ret); // we write the size we get
}
}
// close everithing
for(j=0; j<N_CHILDREN; j++) {
close(p[j][1]); // needed, see text after
}
close(fdi); // close read file
return(0); // main returns a int, 0 is "ok"
}
You have to close every parts of pipes when not needed or when it is over. Until a file descriptor is open a read will block the process. Only when last write counterpart is closed the read returns <=0.
Note: 1. the correct usage of read/write function 2. checking for errors 3. reading from the file and writing to the pipe(s) 4. dealing with effective amount of data read (ret variable) so that you can write (to "screen" or to an other file descriptor the right amount of data.
You're not reading anything in to buf as far as I can tell.

How to wait till data is written on the other end of pipe

I am developing an application in C.
Parent and child process communicate through pipe.
Before writing to pipe, parent process execute another statements. In sample code, i have used sleep(10) to make delay.
In the child process, it should read the data from the pipe.
But data is not read on the read end of pipe in child process.
int main()
{
int pid;
FILE *fp;
fp = fopen("test.txt","w");
char *buff;
int fd[2];
int count = 0 ;
pipe(fd);
pid = fork();
if(pid == 0)
{
close(fd[1]);
ioctl(fd[0], FIONREAD, &count);
fprintf(fp,"Value of count: %d ",count);
buff = malloc(count);
fprintf(fp,"\n TIME before read: %s",__TIME__);
read(fd[0], buff, count);
fprintf(fp,"\nbuffer: %s\n TIME after read %s", buff, __TIME__);
}
else{
close(fd[0]);
sleep(10); //delay caused by application specific code replaced with sleep
write(fd[1],"THIS is it",10);
}
fclose(fp);
return 0;
}
How to make child process wait till data is written on the other end?
Your pipe is opened in blocking mode, and you do nothing to change that, which is likely what you intended.
However, since the first thing you do is request the size of data waiting on the pipe, then blindly jump into reading that many bytes (which in all likelihood will be zero at the time that code executes since the parent hasn't written anything yet) you don't block, and instead just leave because you requested nothing.
There are a number of ways to do this, including a select-loop. If you would rather block on a read until data is available, then do so on a single byte and fill in the remaining data afterward.
This is by no means an example of how to do this right, but it is a short sample of how you can wait on a single byte, request the read-size of the pipe to get the rest of the data, read it, and continue this until the pipe has no data left and the parent shuts down their end:
I hope you find it helpful.
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
int main()
{
int pid = 0;
// create pipe pair
int fd[2];
pipe(fd);
pid = fork();
if (pid == 0)
{
// child side
char *buff = NULL;
char byte = 0;
int count = 0;
// close write side. don't need it.
close(fd[1]);
// read at least one byte from the pipe.
while (read(fd[0], &byte, 1) == 1)
{
if (ioctl(fd[0], FIONREAD, &count) != -1)
{
fprintf(stdout,"Child: count = %d\n",count);
// allocate space for the byte we just read + the rest
// of whatever is on the pipe.
buff = malloc(count+1);
buff[0] = byte;
if (read(fd[0], buff+1, count) == count)
fprintf(stdout,"Child: received \"%s\"\n", buff);
free(buff);
}
else
{ // could not read in-size
perror("Failed to read input size.");
}
}
// close our side
close(fd[0]);
fprintf(stdout,"Child: Shutting down.\n");
}
else
{ // close read size. don't need it.
const char msg1[] = "Message From Parent";
const char msg2[] = "Another Message From Parent";
close(fd[0]);
sleep(5); // simulate process wait
fprintf(stdout, "Parent: sending \"%s\"\n", msg1);
write(fd[1], msg1, sizeof(msg1));
sleep(5); // simulate process wait
fprintf(stdout, "Parent: sending \"%s\"\n", msg2);
write(fd[1], msg2, sizeof(msg2));
close(fd[1]);
fprintf(stdout,"Parent: Shutting down.\n");
}
return 0;
}
Output
Parent: sending "Message From Parent"
Child: count = 19
Child: received "Message From Parent"
Parent: sending "Another Message From Parent"
Parent: Shutting down.
Child: count = 27
Child: received "Another Message From Parent"
Child: Shutting down.
I think after
ioctl(fd[0], FIONREAD, &count);
the count is 0.
read(fd[0], buff, count) will get no data.
try
read(fd[0], buff, 10)
The problem is with getting number of bytes written to the pipe. You are getting it right after the fork(). If the read process executes first, it will contain no data (and the count will be zero). If the write process execute first, it will contain some data.
How to make child process wait till data is written on the other end?
Since you opened the pipe in blocking mode, you should read as much data as possible, and not try to get the size of written data.
Here is your modified example that waits for a full message :
#include <stdio.h>
#include <sys/ioctl.h>
int main()
{
int pid;
FILE *fp;
fp = fopen("test.txt","w");
char *buff = malloc(1024);
int fd[2];
int count = 0 ;
pipe(fd);
pid = fork();
if(pid == 0)
{
close(fd[1]);
int i = 0;
while ( i < 10 )
{
fprintf(fp,"\n TIME before read: %s \n",__TIME__);
read(fd[0], buff+i, 1);
++ i;
}
fprintf(fp,"Full message received!\nbuffer: %s\n TIME after read %s\n", buff, __TIME__);
}
else{
close(fd[0]);
sleep(10); //delay caused by application specific code replaced with sleep
write(fd[1],"THIS is it",10);
}
fclose(fp);
return 0;
}

fork() and pipe()

I need help with this sample application. When I run it, it gets stuck after the child process prints "Child sending!".
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#define INPUT 0
#define OUTPUT 1
int main()
{
int fd1[2];
int fd2[2];
int pid;
if (pipe(fd1) < 0)
exit(1);
if (pipe(fd2) < 0)
exit(1);
if ((pid = fork()) < 0)
{
perror("fork");
exit(1);
}
else if (pid == 0)
{
close(fd1[INPUT]);
close(fd2[OUTPUT]);
char *str = "Hello World!";
printf("Child sending!\n");
write(fd1[OUTPUT], str, strlen(str));
char *bufferc = (char *)malloc(1000);
char *readbufferc = (char *)malloc(80);
int rdc;
int gotdata = 0;
while (gotdata == 0)
while ((rdc = read(fd2[INPUT], readbufferc, sizeof(readbufferc))) > 0)
{
strncat(bufferc,readbufferc,rdc);
gotdata = 1;
}
printf("Child received: %s",bufferc);
free(readbufferc);
free(bufferc);
exit(0);
}
else
{
close(fd1[OUTPUT]);
close(fd2[INPUT]);
int rd;
char *buffer = (char *)malloc(1000);
char *readbuffer = (char *)malloc(80);
int gd = 0;
while (gd == 0)
while ((rd = read(fd1[INPUT],readbuffer, sizeof(readbuffer))) > 0)
{
strncat(buffer, readbuffer,rd);
gd = 1;
}
printf("Parent received: %s\n",buffer);
free(readbuffer);
printf("Parent sending!");
write(fd2[OUTPUT], buffer, strlen(buffer));
free(buffer);
}
return 0;
}
On a side note, is there a way to debug when I use fork because gdb automatically goes to the parent process
After the child writes to the parent, it must close the write end of the pipe so the parent knows it has reached EOF.
There are many bugs in your code. Why are you using fd2 without initializing it? Remove it.
Now its stuck at "Child sending" because pipe read is a blocking call and you are putting it in a while loop which will never return. Please refer to man page of pipe.
If you want to break that while loop, close all write ends of that pipe.
Also to debug child process, use gdb command follow-fork-mode as child before call to fork() while debugging.
Several things wrong:
fd2 is just never initialized.
The parent will never exit this:
while ((rd = read(fd1[INPUT],readbuffer, sizeof(readbuffer))) > 0)
{
strncat(buffer, readbuffer,rd);
gd = 1;
}
If there is no data to read, read will block and just not return. The only thing that would make it exit is if the connection was closed and the child doesn't close it.
You are calling read() in the expectation that if there is nothing to read, it will return with zero bytes read. However, what you are seeing is because read() is waiting for some data before returning. To address this, you need to do one of two things:
set your socket to do non-blocking reads (not recommended)
use select() or poll() to see whether there is some data to read before you read it
Also, several other points:
don't cast the returns from malloc()
check that malloc() does not return NULL
replace the whole gotdata thing with a break instruction

Forks and Pipes in C UNIX

I'm not sure if I am even barking up the right tree here... but here goes.
I'm trying to pass data from my parent process to all children. It's a simple server program that basically will keep a list of connected clients and then send the routing table of connected clients to every client. This is eventually going to include a struct of information about each client... but for right now I just want to get every forked process to get the same information from the parent.
In the parent process, first I set up my pipes and set them to nonblocking (for when there isn't any new data available in the pipe). After a connection is made with a client the number of entries variable is increased to reflect this new connection. I then fork a child process to a new function and update my array of pipes with the new number of table entries (I have 10 pipes at the moment to see if I needed to keep a separate pipe for each child).
pid_t pid;
int numchildren;
int i, n;
/* Create the pipes. */
for(i = 0; i < 10; i++)
{
if (pipe (mypipe[i]))
{
fprintf (stderr, "Pipe failed.\n");
return EXIT_FAILURE;
}
}
for(i = 0; i < 10; i++)
{
for(n=0; n<2; n++)
{
// Get previous flags
int f = fcntl(mypipe[i][n], F_GETFL, 0);
// Set bit for non-blocking flag
f |= O_NONBLOCK;
// Change flags on fd
fcntl(mypipe[i][n], F_SETFL, f);
}
//close(mypipe[i][0]);
}
pid = fork();
if (pid == (pid_t) 0)
{
close (mypipe[numentries-1][1]);
recievecmds(new_fd, mypipe[numentries-1][0]);
close(new_fd);
return EXIT_SUCCESS;
}
else if (pid < (pid_t) 0)
{
fprintf (stderr, "Fork failed.\n");
return EXIT_FAILURE;
}
else
{
sprintf (buf,"%d",numentries);
for(i = 0; i < 10; i++)
write(mypipe[i][1], buf, strlen(buf));
memset(&buf, 0, sizeof buf);
}
And then I try to read whats in the pipe in the recievecmds() function:
nbytes = read(mypipe[childindex][0], buf, sizeof(buf));
The first client connected tells me numentries = 1, the second client tells me numentries = 2 and so on. I mean I really don't even see the point for a pipe since it seems that whatever I put in the pipe I could just pass it in the function I called on the fork. Am I going about this the wrong way? It's been very frustrating trying to figure this out. How can I keep all of my child processes updated concurrently from my parent process?
Thank you so much in advance.
edit - My main problem was that I was redeclaring the pipe everytime in an infinite while loop. Very dumb mistake, immediately realized that was probably the root of my problem. However, while now the first child/pipe combo contains the correct data... the second does not. I'll see if I can figure this out on my own, thanks for the advice!
Of course now I'm running into problems because I manually select an option to get the data off the pipe. I'm going to have to think up a way to maybe either get the data for all pipes every time it's updated or make sure to get just the newest data (probably just one char at a time).
Thanks for putting up with me guys! And I apologize about not posting the whole program... but there's quite a bit. I definitely should have mentioned that I have it in an infinite loop.
Various observations
Don't make the pipes non-blocking; you want the children to block when there's no data. At least, in the early phases of the design; later, you may want to let them get on with work when there's no data waiting.
You need to be careful with your plumbing. The parent needs 10 pipes, one for each child. But it only needs the write end of the pipe, not the read end.
The children each need one pipe, for reading. Any superfluous pipes (for example, the write ends of the pipes that the parent had already opened before forking the Nth child) need to be closed.
You could consider using threads - in which case you could perhaps pass the data to the children. But in the long term, it appears that you will be periodically passing data to the children, and then you need a mechanism to get the data to them (other than the function call).
Pipes are 'easy' as long as you pay meticulous attention to which file descriptors are in use. Close all the descriptors you do not need.
The parent will have to loop around all ten pipes writing the same data to each.
It will also need to consider what to do if a child exits. It should close the pipe (no use any more), and decide whether to start a new child (but how will it ensure that the new child has all the accumulated information it needs?).
Watch out for SIGPIPE - maybe install a handler, or maybe use SIG_IGN and detect write errors instead of signals.
Working code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
enum { NUM_CHILDREN = 10 };
enum { NUM_MESSAGES = 10 };
static int write_pipes[NUM_CHILDREN];
static int n_pipes;
static void be_childish(int *pipe)
{
int i;
char buffer[32];
int nbytes;
int pid = getpid();
close(pipe[1]);
for (i = 0; i < n_pipes; i++)
close(write_pipes[i]);
printf("Child %d\n", pid);
while ((nbytes = read(pipe[0], buffer, sizeof(buffer))) > 0)
{
printf("Child %d: %d %.*s\n", pid, nbytes, nbytes, buffer);
fflush(0);
}
printf("Child %d: finished\n", pid);
exit(0);
}
int main(void)
{
pid_t pid;
int i, j;
/* Create the pipes and the children. */
for (i = 0; i < NUM_CHILDREN; i++)
{
int new_pipe[2];
if (pipe(new_pipe))
{
int errnum = errno;
fprintf(stderr, "Pipe failed (%d: %s)\n", errnum, strerror(errnum));
return EXIT_FAILURE;
}
if ((pid = fork()) < 0)
{
int errnum = errno;
fprintf(stderr, "Fork failed (%d: %s)\n", errnum, strerror(errnum));
return EXIT_FAILURE;
}
else if (pid == 0)
{
be_childish(new_pipe);
}
else
{
close(new_pipe[0]);
write_pipes[n_pipes++] = new_pipe[1];
}
}
for (i = 0; i < NUM_MESSAGES; i++)
{
char message[30];
int len;
snprintf(message, sizeof(message), "Message %d", i);
len = strlen(message);
for (j = 0; j < n_pipes; j++)
{
if (write(write_pipes[j], message, len) != len)
{
/* Inferior error handling; first failure causes termination */
fprintf(stderr, "Write failed (child %d)\n", j);
exit(1);
}
}
sleep(1);
}
printf("Parent complete\n");
return 0;
}
I'd suggest using a shared memory segment. Your parent and child processes can mmap the same file, and read/write state to it. This can be an actual file, or an anonymous memory segment. This is exactly what Apache does with their ScoreBoardFile.

Resources