问题
I need to create a client-server app (using sockets), the basic idea is:
- client sends string
- server receives string and sends it as stdin of another app
- server reads stdout of the app
- server sends answer to client.
The "other app" is a closed source calc (a calculator which reads from stdin the sort of 4 5 +
and prints 9
).
I'm trying to create a double pipe on the server, fork, and use this pipes to redirect stdin and stdout of the calc:
if(!fork())
{
close(STDOUT_FILENO);
close(STDIN_FILENO);
dup2(outfd[0], STDIN_FILENO);
dup2(infd[1], STDOUT_FILENO);
close(outfd[0]); /* Not required for the child */
close(outfd[1]);
close(infd[0]);
close(infd[1]);
system("./calc/calc ");
exit(0);
}
and from the server write on one pipe and read the other
close(outfd[0]); /* These are being used by the child */
close(infd[1]);
char c;
do
{
c=getchar();
write(outfd[1],&c,1);
}while(c!='\n');
input[read(infd[0],input,100)] = 0; /* Read from child’s stdout */
printf("%s",input);
close(outfd[1]);
close(infd[0]);
I know this is very incomplete, but I think it should at least print the output of the first line in calc.
(Full code)
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int outfd[2];
int infd[2];
pipe(outfd); /* Where the parent is going to write to */
pipe(infd); /* From where parent is going to read */
if(!fork())
{
close(STDOUT_FILENO);
close(STDIN_FILENO);
dup2(outfd[0], STDIN_FILENO);
dup2(infd[1], STDOUT_FILENO);
close(outfd[0]); /* Not required for the child */
close(outfd[1]);
close(infd[0]);
close(infd[1]);
//system("/usr/bin/bc -q");
system("./calc/calc ");
exit(0);
}
else
{
char input[100];
close(outfd[0]); /* These are being used by the child */
close(infd[1]);
//write(outfd[1],"2^32\n",5); /* Write to child’s stdin */
//write(outfd[1],"2 4 +\n",6);
char c;
do
{
c=getchar();
write(outfd[1],&c,1);
}while(c!='\n');
input[read(infd[0],input,100)] = 0; /* Read from child’s stdout */
printf("%s",input);
close(outfd[1]);
close(infd[0]);
}
return 0;
It's very basic, but it's just for testing. When I execute it, it does nothing.
If I ps -e | grep calc
during the execution, I can see it is running, but whatever I type doesn't seems to do anything.
回答1:
Try moving:
close(outfd[1]);
between the do-while
loop and input[read(infd[0],input,100)] = 0;
.
This will send EOF
on calc
's stdin. It will exit, and this will flush its output buffer, so there will be something to read.
Your code is deadlocked: you're waiting for output before you close the pipe, but it's waiting for you to close the pipe before it sends output.
来源:https://stackoverflow.com/questions/27736042/redirect-stdin-and-stdout-in-child-in-c