You problem is that in the parent, you carefully close myPipe[0]
, and then mysteriously decide to write to it instead of the still open myPipe[1]
. If you error checked your system calls, you'd know that you'd failed to send any data to the child. As it is, the child is still waiting for the data to arrive, and won't exit, and the parent is waiting for the child that won't exit to exit, so you have a deadlock.
I'm using the error reporting functions from stderr.c
and stderr.h
— the code for which is available from GitHub (https://github.com/jleffler/soq/tree/master/src/libsoq) to report errors (and progress).
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include "stderr.h"
static int myPipe[2];
int main(int argc, char **argv)
{
pid_t pid;
int value;
int status;
err_setarg0(argv[0]);
err_setlogopts(ERR_PID|ERR_MICRO);
if (pipe(myPipe) != 0)
err_syserr("pipe failed: ");
// call fork()
printf("CS201 - Assignment 3 Premium - I. Forgot\n");
pid = fork();
if (pid < 0)
err_syserr("fork failed: ");
else if (pid == 0)
{
// -- running in child process --
int sum = 0;
if (close(myPipe[1]) != 0)
err_syserr("failed to close write end of pipe in child: ");
for (int i = argc; i > 1; i--)
{
if (read(myPipe[0], &value, sizeof(value)) != sizeof(value))
err_syserr("failed to read from parent: ");
sum += value;
}
if (close(myPipe[0]) != 0)
err_syserr("failed to close read end of pipe in child: ");
err_remark("Exiting: sum = %d\n", sum);
return sum;
}
else
{
// -- running in parent process --
int sum = 0;
close(myPipe[0]);
for (int i = argc; i > 1; i--)
{
value = atoi(argv[i - 1]);
err_remark("Writing: %d\n", value);
if (write(myPipe[1], &value, sizeof(value)) != sizeof(value))
err_syserr("failed to write to child: ");
}
if (waitpid(pid, &status, 0) != pid)
err_syserr("failed to wait for child %d: ", pid);
sum = status;
printf("sum = %d\n", sum);
if (WIFEXITED(status))
printf("exit status: %d\n", WEXITSTATUS(status));
return 0;
}
}
And example output (source code in fp71.c
, program fp71
):
$ gcc -O3 -g -I./inc -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
> -Wstrict-prototypes fp71.c -o fp71 -L./lib -lsoq
$ fp71 1 2 4 7
CS201 - Assignment 3 Premium - I. Forgot
fp71: 2017-08-15 20:11:48.453688 - pid=86097: Writing: 7
fp71: 2017-08-15 20:11:48.454267 - pid=86097: Writing: 4
fp71: 2017-08-15 20:11:48.454275 - pid=86097: Writing: 2
fp71: 2017-08-15 20:11:48.454281 - pid=86097: Writing: 1
fp71: 2017-08-15 20:11:48.454348 - pid=86098: Exiting: sum = 14
sum = 3584
exit status: 14
$
The decimal value 3584 corresponds to hexadecimal 0x0E00. If you analzye that with WIFEXITED()
and WEXITSTATUS
, then that is equivalent to 14
, as you'd expect. (See also Exit values bigger than 255 — possible?)