Problem
I only get this in the terminal output. I believe the program is getting stuck at the fork()
call but I don't know exactly why.
The name of the program is q9:
prompt>$ ./q9 inputString
Parent: writing to pipe 'inputString'
Task
- read input from terminal into the parent-to-child pipe.
- fork() to create a child process.
- read input from parent-to-child pipe.
- concatenate some other string to that string read in from the pipe.
- write the newly concatenated string to the child-to-parent pipe.
- in the parent, read from the child-to-parent pipe and print the output read from the pipe to the terminal.
Attempts
I have tried fixing this by:
- attempting to close pipes in different places. I thought I may have missed something or left something open, but I don't think so.
- placing a wait() in the parent because perhaps it wasn't letting the child run completely
- attempted to print the output of the concatenated string just in case it was that messing up the prints.
Code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/wait.h>
int main (int argc, char *argv[]) {
// parent RUN
if(argc == 1) {
printf("usage: q9 <string>\n");
return 0;
}
// create two way pipes
int parent_fds[2], child_fds[2];
// create strings to save too
char fromParent[100];
char fromChild[100];
// read:[0] - write:[1]
if (pipe(parent_fds) != 0 && pipe(child_fds) != 0) {
fprintf(stderr, "pipes failed!\n");
}
// close unused pipe end by parent
close(parent_fds[0]);
close(child_fds[1]);
close(child_fds[0]);
// write from terminal to parent pipe FOR child to read
printf("Parent: writing to pipe '%s'\n", argv[1]);
write(parent_fds[1], argv[1], strlen(argv[1]));
close(parent_fds[1]);
// fork() child process
int child = fork();
// NEVER GETS PASSED HERE :(
if (child < 0) {
fprintf(stderr, "fork failed!");
exit(1);
} else if (child == 0) {
printf("I reached the child :)");
// close unwanted pipe ends by child
close(child_fds[0]);
close(parent_fds[1]);
// read from parent pipe
int n = read(parent_fds[0], fromParent, 100);
fromParent[n] = 0;
printf("Child: reading from parent pipe '%s'\n", fromParent);
close(parent_fds[0]);
// Concatinate to what was read in
const char myText[14] = " (added this.)";
strcat(fromParent, myText);
write(child_fds[1], fromParent, strlen(fromParent));
close(child_fds[1]);
printf("Child: writing to pipe - '%s'\n", fromParent);
} else {
// read from child pipe
int n = read(child_fds[0], fromChild, 100);
fromChild[n] = 0;
printf("Parent: reading from pipe - '%s'\n", fromChild);
}
return 0;
}
fork
first. Then do the respective parent and childclose
calls followed by the respectiveread
andwrite
calls. – kaylumstderr
. When you write tostdout
(in particular; also for writing tostderr
), ensure that you end messages with a newline. Consider usingfflush(stdout);
to ensure the output is visible. Include PID numbers in output — usegetpid()
in the printing call to make sure you don't get stale values acrossfork()
calls. – Jonathan Leffler