I ran into a problem with this C exercise. The task is to create two processes. The two are connected with two pipes that terminate in the stdin and stdout of the child. The child process is then replaced with bc. I am then supposed to write a term (e.g. 1 + 2) from the parent to the child process (bc).
The pipes are doing what they're supposed to do, however, bc doesn't seem to like the input. When I write into the pipe, bc responds with multiple lines of the following:
(standard_in) 1: illegal character: ^@
This is my solution so far:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
/*Create two pipes:
One from parent to child (pipe_pc)
and one from child to parent (pipe_cp).
*/
int pipe_pc[2], pipe_cp[2];
int cid;
if (pipe(pipe_pc) == -1 || pipe(pipe_cp) == -1) {
printf("Could not pipe\n");
exit(EXIT_FAILURE);
}
// Create child process
cid = fork();
if (cid == -1) {
printf("Could not fork.\n");
exit(EXIT_FAILURE);
}
// Child process
if (cid == 0) {
// Redirect pipes
close(STDOUT_FILENO);
close(STDIN_FILENO);
close(pipe_pc[1]); // Close writing end
close(pipe_cp[0]); // Close reading end
dup2(pipe_pc[0], STDIN_FILENO); // Take stdin from parent
dup2(pipe_cp[1], STDOUT_FILENO); // Give stdout to parent
int err;
// Replace child with bc
err = execl("/usr/bin/bc", "bc --quiet", (char*) NULL);
printf("%s %d\n", "Could not start bc:", err);
exit(err);
}
// Parent Process
else {
char input[128] = "";
char buffer[128] = "";
printf("%s\n", "Parent process running");
// Copy argv to a single string
for(int i=1; i < argc; i++) {
strcat(input, argv[i]);
}
// Write the input to the child's stdin
write(pipe_pc[1], input, sizeof(input);
// Read the child's stdout
read(pipe_cp[0], buffer, sizeof(buffer));
printf("Result: %s\n", buffer);
return 0;
}
}
Hints and help are greatly appreciated, thanks in advance!
The problem was that you did not write correctly in the pipe, so bc received bad input.
I rewrote the
else
branch.If you are not sure what you send in a pipe, replace temporarily the pipe descriptor with 0 (i/o fd) and check visually what you did.
Your code has a lot of undefined behavior.
You write all input array. But you need to only write what you copy with
strcat()
. Use strlen.here you should verify that you don't exceed 128 octet.
here you don't verify that buffer is a valid c string.
You forget to close pipe in the parent
and after your read/write
You forget to close pipe in child after your
dup2()
You don't need to close your old fd before dup2, he do it for you. And you don't check error of
dup2()