Reputation: 337
I'm trying to create a two-way communication between parent and child processes using 2 pipes using C on Linux. The parent is my program and the child is just a random program (say "cat").
I try to uses read()
in parent to read child output, but it gives me errno 9, which is Bad file descriptor.
The following is my code
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define Read 0
#define Write 1
#define ParentRead read_pipe[1]
#define ParentWrite write_pipe[0]
#define ChildRead write_pipe[1]
#define ChildWrite read_pipe[0]
int main()
{
int data_processed;
/** Pipe for reading for subprocess */
int read_pipe[2];
/** Pipe for writing to subprocess */
int write_pipe[2];
char buffer[100];
memset(buffer, '\0', 100);
if (pipe(read_pipe) == 0 && pipe(write_pipe) == 0)
{
pid_t pid = fork();
if (pid == (pid_t)-1)
{
fprintf(stderr, "Fork failure");
exit(EXIT_FAILURE);
}
else if (pid == (pid_t)0) //Child process
{
close(Read);
close(Write);
close(ParentRead);
close(ParentWrite);
dup(ChildRead);
dup(ChildWrite);
execlp("cat", (char*)NULL);
exit(EXIT_FAILURE);
}
else { //Parent process
close(ChildRead);
close(ChildWrite);
write(ParentWrite, "abc", 3);
int r = read(ParentRead, buffer, 99);
printf("%d %d", r, errno);
puts(buffer);
}
}
exit(EXIT_SUCCESS);
}
Upvotes: 4
Views: 18637
Reputation: 816
If you want to redirect stdin and stdout to pipes, you need to use dup2(2) system call.
dup2 (ChildRead, 0);
dup2 (ChildWrite, 1);
P.S. Also I found wrong directions of reading/writing in pipes. Here is the correct way
#define ParentRead read_pipe[0]
#define ParentWrite write_pipe[1]
#define ChildRead write_pipe[0]
#define ChildWrite read_pipe[1]
Remember: pipe[0] is fd for reading, pipe[1] is fd for writing.
And one more error, in execlp. Do not forget to set the first argument you send to the executed programm as a name of the program
execlp("cat", "cat", (char*)NULL);
Upvotes: 3
Reputation: 2097
What happens if you just perform a read/write? I'm unsure that dup and cat are what you want here, to be honest:
char buf[256];
int len;
len = read(ChildRead, 256);
write(ChildWrite, len);
And, thinking further, if you know the fd you want to end up at, use dup2, not dup. Know your APIs, people!
And, thinking even further, you could look at the source for the popen(3) call, which does exactly this, in a more general way.
Upvotes: 0