Reading from pipe issue - c

I am writing on a pipe 10 integers, so i call write 10 times and then i want to call read pipe only once and store the written integers into an array of size 10 and after that add all the integers from the array into a total sum. The problem is that i get only 9 integers after reading. What i am doing wrong?
int main()
{
int fd[2];
int total = 0;
int result;
int nbytes;
int child;
int subVector;
int written;
static int readSum[P];
int partialSum;
if(pipe(fd) < 0){
perror("pipe");
}
for(child = 0; child < P; child++){
if((pid[child] = fork()) < 0){
perror("fork");
exit(1);
}
else if(pid[child] == 0){
close(fd[0]);
partialSum = getSubvectorSum(elementsList,child,P,SIZE);
//printf("Partial sum: %d by child #%d\n",partialSum,getpid());
written = write(fd[1],&partialSum,sizeof partialSum);
//printf("Child #%d has written: %d bytes.\n",getpid(),written);
if(written == 0){
printf("Writting not performed.");
}
close(fd[1]);
exit(0);
}
}
close(fd[1]);
int status = 0;
nbytes = read(fd[0],&readSum,sizeof readSum);
printf("Parent reads %d bytes\n",nbytes);
if(nbytes > 0){
for(child =0;child<P;child++){
total += readSum[child];
printf("Partial sum in father: %d\n",readSum[child]);
}
}
else{
printf("Failed to read.");
}
}

You are ignoring the wisdom of the sage Rolling Stones and not accepting that you can't always get what you want but sometimes you get what you need.
(1) There is no guarantee all your children have run and written to the pipe before the parent tries to read.
(2) There is no guarantee even if (1) did take place that your read would return all 10 integers in one read. read can (and often will) return less than you ask for.
One way to cover this is to have your parent wait on its children so you know they completed and then to read in a loop until you read everything you need.

http://linux.die.net/man/2/read
Read returns available data, not the requested amount, use cycle and check return value on each iteration.

Related

Blocking read with closed file descriptor

I have three processes organized in a circular link: P1->P2->P3->P1. I have 3 unnamed pipes for each of the three links. Each process reads an integer from his neighbour on the left and writes an integer to the neighbour on the write. After some time an termination condition will be satisfied at one of the processes. This will make that process close his open file descriptors and terminate. However, the other processes still are able to write to the now closed fd and the reads are blocking. Have I misunderstood how unnamed pipes are really working?
void monitor(int *fdr, int *fdw, int pid) {
int A,B,ret,avg;
char send_buf[10], recv_buf[10];
srand((unsigned int) fdr);
A = 20;
close(fdr[1]); close(fdw[0]);
while(1) {
B = rand() % 30;
avg = (A+B)/2;
if (avg > 20) {
printf("P%d computes to high avg. Quit!\n",pid);
break;
}
sprintf(send_buf, "%d", avg);
printf("P%d will write %s\n",pid,send_buf);
ret = write(fdw[1],send_buf,strlen(send_buf)+1);
if (ret == 0) {
printf("P%d cant write. Quit\n",pid);
break;
}
printf("P%d successful write=%d\n", pid, ret);
ret = read(fdr[0], recv_buf,10);
if (ret == 0) {
printf("P%d cant read. Quit\n",pid);
break;
}
printf("P%d reads %s\n",pid,recv_buf);
A = atoi(recv_buf);
}
// Closing filedescriptors should also break the other
// processes out of the while loop
close(fdr[0]);
close(fdw[1]);
printf("P%d closed all descriptors\n",pid);
}

Using multiple processes to read a file and sending numbers through pipe()

I have to use fork(2) to make as many children as inputted by the user.
Then I need them to split up the work reading a txt file of coordinate points comparing the distance between them to an inputted distance.
Then they add their count of how many points are within the distance given. Each child has to write their count to the pipe and the parent has to read each count and add it to the total and then print it out. Here is my code:
int main( int argc, char *argv[] ) {
int distance = atoi(argv[1]);
if ( argc != 3 || sscanf( argv[ 1 ], "%d", &distance ) != 1 )
fail( "usage: pairs <distance>" );
readPoints();
int workers = atoi(argv[2]);
// Compute the square of the distance bound, since that's what we'll
// need to compare against.
int dsq = distance * distance;
// Count up the number of nearby pairs of points.
int total = 0;
int fd[2]; // pipe
if ( pipe( fd ) != 0 ){
fail( "Can't create pipe" );
}
int pid; // child
int chNum; // child's number
int c;
for( chNum = 0; chNum < workers; chNum++){
c = 0;
pid = fork();
if ( pid == -1 ){ //failure
fail( "Can't create child process" );
}
if( pid ==0 ){ // it's a child
for ( int i =chNum; i < ptCount; i+=workers)
for ( int j = i + 1; j < ptCount; j++ ) {
// Check the squared distance.
int dx = ptList[ i ].x - ptList[ j ].x;
int dy = ptList[ i ].y - ptList[ j ].y;
if ( dx * dx + dy * dy <= dsq )
c++;
}
close(fd[READ]);
lockf(fd[WRITE], F_LOCK,0);
write(fd[WRITE], &c, sizeof(c));
lockf(fd[WRITE], F_ULOCK,0);
close(fd[WRITE]);
exit(0);
}
else if(pid>0){ // this is parent
int d;
close(fd[WRITE]);
read(fd[READ], &d, sizeof(d));
close(fd[READ]);
total = total + d;
}
}
if(pid>0){
wait(NULL);
printf( "Total: %d\n", total );
}
return 0;
}
I use a for loop to make the children with fork(2), and then I have them calculate the count and send it to the pipe to be read by the parent. The parent reads into d and adds it to total. I was wondering if I am using the pipe correctly to send each child's count to the parent and/or if I am forking correctly so it only comes from one parent. I am getting the wrong total count when I use more than 1 child.
If I use 1 child, the total result is 166428, which is correct, but when I use 4 for example, it gives me 164908. Can someone help me?
You're not doing pipe handling properly.
First off, you don't need to lock / unlock to write to and read from the pipe: writes that are less than PIPE_BUF bytes are guaranteed to be atomic. POSIX.1-2001 requires that PIPE_BUF is at least 512 bytes; since you're only writing sizeof(int) bytes at a time, you're safe (unless sizeof(int) is greater than or equal to 512, which is nonsense). See man limits.h, under Pathname Variable Values:
{PIPE_BUF}
Maximum number of bytes that is guaranteed to be atomic
when writing to a pipe. Minimum Acceptable Value: {_POSIX_PIPE_BUF}
That by itself simplifies the code and reduces unnecessary locking / unlocking overhead.
But the real issue is here:
else if (pid > 0) { // this is parent
int d;
close(fd[WRITE]);
read(fd[READ], &d, sizeof(d));
close(fd[READ]);
total = total + d;
}
You can't close fd[WRITE] inside the loop: consider what happens in the next iteration, when you fork the next process. The child process in the next loop will attempt to write to a file descriptor that has already been closed, so an error occurs (and write(2) fails with EBADF, but you never check the return value of write(2) so the code happily ignores the error). Plus, you attempt to close fd[WRITE] again and again, so close(2) will also return an error (which again, you ignore).
Similarly for read(2): if you close fd[READ], you can't read the results out of the pipe in the next iteration; read(2) will return an error and close(2) too.
(So the lesson is: do not ignore errors. If you had done error handling properly, you would have a pretty strong clue at what was going wrong)
You don't need to close. The child processes write exactly workers integers to the pipe; the parent process reads exactly workers integers from the pipe, so this is enough:
for (chNum = 0; chNum < workers; chNum++) {
c = 0;
pid = fork();
if (pid == -1)
fail("Can't create child process");
if (pid == 0) { // it's a child
for (int i = chNum; i < ptCount; i += workers) {
for (int j = i + 1; j < ptCount; j++) {
// Check the squared distance.
int dx = ptList[i].x - ptList[j].x;
int dy = ptList[i].y - ptList[j].y;
if (dx*dx + dy*dy <= dsq) {
c++;
}
}
}
ssize_t written = write(fd[WRITE], &c, sizeof(c));
if (written == -1)
perror("write error");
if (written != sizeof(c))
fail("Write failed on pipe");
exit(0);
}
else {
int d;
if (read(fd[READ], &d, sizeof(d)) != sizeof(d))
fail("Read error on pipe");
total += d;
}
}
The key point is to understand that you need to keep fd[READ] and fd[WRITE] open as long as you plan to fork new processes that will use the pipe.
Now, that fixes the problem, but you get a false sense of parallelism: reads in a pipe will block by default if no data is available. This means that on each iteration, the parent will not make progress until the corresponding child writes to the pipe. So you're not really parallelizing anything; the effect is the same as having the parent fork, wait for the child to terminate, read the result and add it to total, and then fork the next child (and repeat the cycle).
If you want true parallelism, you have to fork every process and only then start reading from the pipe. Something like this:
for (chNum = 0; chNum < workers; chNum++) {
c = 0;
pid = fork();
if (pid == -1)
fail("Can't create child process");
if (pid == 0) { // it's a child
for (int i = chNum; i < ptCount; i += workers) {
for (int j = i + 1; j < ptCount; j++) {
// Check the squared distance.
int dx = ptList[i].x - ptList[j].x;
int dy = ptList[i].y - ptList[j].y;
if (dx*dx + dy*dy <= dsq) {
c++;
}
}
}
ssize_t written = write(fd[WRITE], &c, sizeof(c));
if (written == -1)
perror("write error");
if (written != sizeof(c))
fail("Write failed on pipe");
exit(0);
}
}
if (close(fd[WRITE]) < 0)
fail("Error closing pipe's write channel");
int d;
ssize_t r;
while ((r = read(fd[READ], &d, sizeof(d))) > 0) {
if (r != sizeof(d))
fail("read error");
total += d;
}
Note that here we have to explicitly close the pipe's write channel before starting the reads; this is to avoid having the parent hang when no more child processes are actively writing to the pipe. Remember that a read will block as long as there is at least one process with the pipe's write channel open. If the parent process kept the write channel open, read(2) would never return because there is a chance that the parent himself could write to the pipe (even though we know it won't). So we have to close fd[WRITE].
Alternatively, since we know that there are exactly workers numbers to read from the pipe, we could just do this after the loop instead of closing the write channel:
int d;
int i;
for (i = 0; i < workers; i++) {
if (read(fd[READ], &d, sizeof(d)) != sizeof(d))
fail("Failed to read from pipe");
total += d;
}
A couple of other (unrelated) remarks:
The error message when the wrong arguments are given does not agree with the code. The code shows that distance is in argv[1] and workers is in argv[2], yet the error message passed to fail() seems to say that distance is in argv[2].
argv[1] is parsed twice as an integer: with atoi(3) and with sscanf(3). I'd stick to sscanf(3) since you can check the return value to make sure that parsing was successful.
workers is not validated and is converted with atoi(3). Errors are ignored. I'd suggest parsing it with sscanf(3) just like you did with distance and make sure that it is successful.
The correct type to store a pid is pid_t, not int. Please use the correct type (you might have to include sys/types.h in addition to unistd.h).
Here's the final version with all of this sorted out:
int main(int argc, char *argv[]) {
int distance;
int workers;
if (argc != 3 || sscanf(argv[1], "%d", &distance) != 1 || sscanf(argv[2], "%d", &workers) != 1)
fail("usage: <distance> <workers>");
readPoints();
// Compute the square of the distance bound, since that's what we'll
// need to compare against.
int dsq = distance * distance;
// Count up the number of nearby pairs of points.
int total = 0;
int fd[2]; // pipe
if (pipe(fd) != 0)
fail("Can't create pipe");
pid_t pid;
int chNum; // child's number
int c;
for (chNum = 0; chNum < workers; chNum++) {
c = 0;
pid = fork();
if (pid == -1)
fail("Can't create child process");
if (pid == 0) { // it's a child
for (int i = chNum; i < ptCount; i += workers) {
for (int j = i + 1; j < ptCount; j++) {
// Check the squared distance.
int dx = ptList[i].x - ptList[j].x;
int dy = ptList[i].y - ptList[j].y;
if (dx*dx + dy*dy <= dsq) {
c++;
}
}
}
ssize_t written = write(fd[WRITE], &c, sizeof(c));
if (written == -1)
perror("write error");
if (written != sizeof(c))
fail("Write failed on pipe");
exit(0);
}
}
if (close(fd[WRITE]) < 0)
fail("Error closing pipe's write channel");
int d;
ssize_t r;
while ((r = read(fd[READ], &d, sizeof(d))) > 0) {
if (r != sizeof(d))
fail("read error");
total += d;
}
printf("Total: %d\n", total);
return 0;
}

C - create two processes which can generate odd and even integers

I have this assignment where I have to create two processes and each process has to generate 50 integers which are odd or even.
Write a simple sequence-number system through which two processes, P1 and P2, can each obtain 50 unique integers, such that one receives all the odd and the other all the even numbers. Use the fork() call to create P1 and P2. Given a file, F, containing a single number, each process must perform the following steps:
a. Open F.
b. Read the sequence number N from the file.
c. Close F.
d. Output N and the process' PID (either on screen or test file).
e. Increment N by 1
f. Open F.
g. Write N to F.
h. Flush F.
i. Close F
As suggested by SO user I have created a loop in each process and ran the steps as mentioned above. But I am not sure if this approach is correct. I have asked my Teaching assistant for help and he suggested to do the same(using sleep call and waiting for a valid integer). But the thing is I can obtain the same results without using the sleep call. So I am not sure if I am applying the logic properly to code. Can someone please help?
This is my implementation:
void getUniqueNumbers() {
struct process p1;
struct process p2;
int numberFromFile;
pid_t pid = fork();
// Process 1
if (pid == 0) {
int p1Counter = 0;
p1.processId = getpid();
while(p1Counter < numLimit) {
numberFromFile = getNumberFromFile();
if (numberFromFile % 2 == 0) { // even
p1.numbers[p1Counter] = numberFromFile;
printf("N: %d, PID: %d\n", numberFromFile, p1.processId);
numberFromFile++;
writeNumberToFile(numberFromFile);
p1Counter++;
}
else {
sleep(1);
}
}
}
// Process 2
else if (pid > 0 ) {
int p2Counter = 0;
p2.processId = getpid();
while(p2Counter < numLimit) {
numberFromFile = getNumberFromFile();
if (numberFromFile % 2 != 0) { // odd
p2.numbers[p2Counter] = numberFromFile;
printf("N: %d, PID: %d\n", numberFromFile, p2.processId);
numberFromFile++;
writeNumberToFile(numberFromFile);
p2Counter++;
}
else {
sleep(1);
}
}
}
else {
printf("Error: Could not create process\n");
}
}
Read/Write functions:
// Returns the number included in user provided file
int getNumberFromFile() {
FILE *fp = fopen(fileName, "rb");
int num = 0;
if (fp != 0) {
char line[10];
if (fgets(line, sizeof(line), fp) != 0)
num = atoi(line);
fclose(fp);
}
return num;
}
// Writes a given number to the user provided file
void writeNumberToFile(int num) {
FILE *fp = fopen(fileName, "w");
if (fp != 0) {
fprintf(fp, "%d", num);
fclose(fp);
}
}
The code looks ok. It can be simplified a lot though.
void getUniqueNumbers()
{
struct process p; // We need only 1 structure
size_t counter = 0; // sample counter
int oddEven; // flag if we are parent
pid_t pid = fork(); // Fork here
if (-1 == pid)
{
abort(); // simply die on error
}
oddEven = 0 == pid ? 0 : 1;
p.processId = getpid(); // We are either child or parent.
while (counter < numLimit)
{
int numberFromFile = getNumberFromFile();
if ((numberFromFile & 1) == oddEven)
{
p.numbers[counter++] = numberFromFile;
printf("N: %d, PID: %ld\n", numberFromFile, (long)p.processId);
numberFromFile++;
writeNumberToFile(numberFromFile);
}
sleep(1); // sleep in both cases
// Extra check for parent: if child has died, we are in infinite
// loop, so check it here
if (0 != pid && counter < numLimit)
{
int status = 0;
if (waitpid(pid, &status, WNOHANG) > 0)
{
printf("Child exited with 0x%08X status\n", status);
break;
}
}
}
// wait till child process terminates
if (0 != pid)
{
int status = 0;
waitpid(pid, &status, 0);
printf("Child exited with 0x%08X status\n", status);
}
}
Also, the file reading/writing either should use file lock operations, or atomic file change. It is important to prevent potential errors like one thread is writing number 40006, and another one manages to read 400. Should not happen in real life though.
File locks are needed to prevent concurrent access to the same contents. It can be exclusive lock, or shared read exclusive write.
Atomic modifications are feature that enables to replace file contents atomically, regardless of how many operations it took to write the data. It is an alternative to keep data consistent.

Write and read on pipe a list of unknown size

I want to write on a pipe an array with an unknown size.The array's values are read from stdin. Below is a part of the code that i have written so far. The problem is that using the count variable i am writing exactly 0 bytes. When i should allocate memory for the array in which i perform the read? It's there a better way to make this work?
#include<stdio.h>
#include<unistd.h>
int main(){
int fd[2];
int *values;
int *received;
pid_t child;
int count = 0;
if(pipe(fd) != 0){
perror("pipe");
}
if((child = fork()) < 0){
perror("fork");
}
else if(child == 0)
{
close(fd[0]);
while(enteringValues){
//get values from stdin
//allocating memory for each read element
count++;
}
write(fd[1],values,count*sizeof(values[0]));
close(fd[1]);
exit(0);
}
close(fd[1]);
int i;
int nbytes = read(fd[0],&received,count*sizeof(received[0]));
for(i = 0;i<count;i++){
printf("%d received \n",received[i]);
}
return 0;
}
Pipes send bytes from one place to another. So you need to precisely specify what bytes you are going to send. Then make sure your sending code sends precisely those bytes and your receiving code expects precisely those bytes.
If you want it to work without having to do things the right way, do this:
Sender:
write(f[1], &val, sizeof(int));
Receiver:
for (int i = 0; i < 3; ++i)
read(f[0], &buf[i], sizeof(int));
Note also printf("%d", *buff); prints the first element in the array (element zero).
Do not change the receiving code to read(f[0], buf, 3 * sizeof(int));. Your write is not atomic (because you call write three times) so you can't expect your read to be.

Using pipe to pass integer values between parent and child

I'm a little confused on how to properly use pipe() to pass integer values between two processes.
In my program I first create a pipe, then I fork it. I assume I have "Two" pipes then?
From what I understand, this is my assignment.
My parent goes through a for loop checking an integer value "i" for a certain operation, increases a count variable, and saves value into an array. After each check my parent should pass an integer value, "i" to my child through a pipe. My child then uses that integer value, does some check on the value, and should increase a count variable, and save the result in a [shared?] array. Eventually; the child should return it's final count to the parent, who then prints out the two counts, and the "Shared" array.
-> I'm not sure I need to have a shared array or to save the results at all. I may only need the counts - the homework was ambiguous and I'm awaiting a response from the professor. Also; can I even do a shared array between processes? It sounds like a start of some problem to me.
-> Here are my questions:
One; how do I use pipes for integers? I've only seen them for character arrays and previous answers don't seem to think this is possible or legal..? I'm not sure. There was no resolution that I could find on it.
-> How do I use a unidirectional pipe to pass integers to a child? And have the child return something? I'm not sure how I'm able to... differentiate between the two pipes. I do "know" [or think I know] that I have to close one unused portion of each pipe to avoid "Some vague problem".
Sorry for the dumb questions; I haven't been taught processes (aside from fork) or pipes (at all) yet in this class - so I'm not really sure where to start!
Heres parts of my code - it's not pretty and it doesn't work and I don't expect it to. It's more of a shell placeholder. Once I figure out how to use a pipe - I'd Probably make the code make sense.
int main(void)
{
int fd[2];
pid_t childpid;
pid_t parentpid;
int i;
int threecount = 0;
int fivecount = 0;;
int results [MAXSIZE];
parentpid = getpid(); //Get current process ID number
pipe(fd);
childpid = fork();
if(childpid == 0){
close(fd[0]); //Closing this for some other reason
}
int j = 0;
if(childpid > 0)
close(fd[1]); //Closing this for some reason
if( childpid == -1 )
{
perror("Failed to fork\n");
return 1;
}
if (childpid > 0)
{
for(i = 1; i < MAXSIZE;i++)
{
if(i % 5 == 0)
{
fivecount++;
i = results[j];
j++;
wait(NULL);
}
}
}
else if (childpid == 0)
{
if(i % 3 == 0) //This i here should probably be the i value above, piped to the child
{
threecount++;
i = results[j]; //This should be part of th pipe
j++; //Trying to keep count of that shared array, not really the right way to do it though.
}
}
printf("%d %d \n", fivecount,threecount);
return 0;
}
This is about as lame (and no error checking, btw) a sample as I can muster for using a pipe to send int from a parent to a child process, where the child was launched from fork(). It gets more complicated (obviously) for sending and receiving data, but i can't do everything for you. This just forks and waits for an int (actually, the number of bytes that are used by an int) from the child.
Update: Added send+response two-way communication example after this one. See the second code listing for more information.
Hope it helps.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int fd[2];
int val = 0;
// create pipe descriptors
pipe(fd);
// fork() returns 0 for child process, child-pid for parent process.
if (fork() != 0)
{
// parent: writing only, so close read-descriptor.
close(fd[0]);
// send the value on the write-descriptor.
val = 100;
write(fd[1], &val, sizeof(val));
printf("Parent(%d) send value: %d\n", getpid(), val);
// close the write descriptor
close(fd[1]);
}
else
{ // child: reading only, so close the write-descriptor
close(fd[1]);
// now read the data (will block)
read(fd[0], &val, sizeof(val));
printf("Child(%d) received value: %d\n", getpid(), val);
// close the read-descriptor
close(fd[0]);
}
return 0;
}
Output:
Parent(5943) send value: 100
Child(5945) received value: 100
Update: Expanded to include send+response using two pipe sets
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
// some macros to make the code more understandable
// regarding which pipe to use to a read/write operation
//
// Parent: reads from P1_READ, writes on P1_WRITE
// Child: reads from P2_READ, writes on P2_WRITE
#define P1_READ 0
#define P2_WRITE 1
#define P2_READ 2
#define P1_WRITE 3
// the total number of pipe *pairs* we need
#define NUM_PIPES 2
int main(int argc, char *argv[])
{
int fd[2*NUM_PIPES];
int val = 0, len, i;
pid_t pid;
// create all the descriptor pairs we need
for (i=0; i<NUM_PIPES; ++i)
{
if (pipe(fd+(i*2)) < 0)
{
perror("Failed to allocate pipes");
exit(EXIT_FAILURE);
}
}
// fork() returns 0 for child process, child-pid for parent process.
if ((pid = fork()) < 0)
{
perror("Failed to fork process");
return EXIT_FAILURE;
}
// if the pid is zero, this is the child process
if (pid == 0)
{
// Child. Start by closing descriptors we
// don't need in this process
close(fd[P1_READ]);
close(fd[P1_WRITE]);
// used for output
pid = getpid();
// wait for parent to send us a value
len = read(fd[P2_READ], &val, sizeof(val));
if (len < 0)
{
perror("Child: Failed to read data from pipe");
exit(EXIT_FAILURE);
}
else if (len == 0)
{
// not an error, but certainly unexpected
fprintf(stderr, "Child: Read EOF from pipe");
}
else
{
// report what we received
printf("Child(%d): Received %d\n", pid, val);
// now double it and send it back
val *= 2;
printf("Child(%d): Sending %d back\n", pid, val);
if (write(fd[P2_WRITE], &val, sizeof(val)) < 0)
{
perror("Child: Failed to write response value");
exit(EXIT_FAILURE);
}
}
// finished. close remaining descriptors.
close(fd[P2_READ]);
close(fd[P2_WRITE]);
return EXIT_SUCCESS;
}
// Parent. close unneeded descriptors
close(fd[P2_READ]);
close(fd[P2_WRITE]);
// used for output
pid = getpid();
// send a value to the child
val = 42;
printf("Parent(%d): Sending %d to child\n", pid, val);
if (write(fd[P1_WRITE], &val, sizeof(val)) != sizeof(val))
{
perror("Parent: Failed to send value to child ");
exit(EXIT_FAILURE);
}
// now wait for a response
len = read(fd[P1_READ], &val, sizeof(val));
if (len < 0)
{
perror("Parent: failed to read value from pipe");
exit(EXIT_FAILURE);
}
else if (len == 0)
{
// not an error, but certainly unexpected
fprintf(stderr, "Parent(%d): Read EOF from pipe", pid);
}
else
{
// report what we received
printf("Parent(%d): Received %d\n", pid, val);
}
// close down remaining descriptors
close(fd[P1_READ]);
close(fd[P1_WRITE]);
// wait for child termination
wait(NULL);
return EXIT_SUCCESS;
}
(compile with, e.g., gcc thisfile.c -o test)
Output
Parent(2794): Sending 42 to child
Child(2797): Received 42
Child(2797): Sending 84 back
Parent(2794): Received 84

Resources