Newbie on forking child process and I/O redirection
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Newbie on forking child process and I/O redirection
Hi, I am new to child process concept under Linux. I want a simple but complete example code that demonstrates the following basics of forking child process:
1. Forking a child process.
2. Redirecting its stdin and stdout.
3. The parent process writes to stdout and at the same time reads child stdout.
Off the top of my head, the best I can do is some pseudocode. It'll be simple, but you have to complete it :-)
Code:
// Pseudocode. This will not compile and/or contain severe syntax errors
// Omitted error checking for simplicity. Don't try this at home
int main ()
{
int fd[2]; // file descriptors
// Create pipe
pipe(fd);
// Fork child process
if (fork() == 0)
{
char buffer [80];
// We're in the child process
// close stdin
close(0);
// connect pipe to stdin
dup(fd[0]);
close(fd[0]);
// read from stdin
gets(buffer);
// Prove that it worked
printf("Parent said %s", buffer);
}
else
{
// We're in the parent process
// close stdout
close(1);
// connect pipe to stdout
dup(fd[1]);
close(fd[1]);
// Write to standard out
printf ("Hello world!\n");
}
// the end
return 0;
}
For details, refer to the manpages of the used functions. Or ask more specific questions
I tested the code, it worked. But it's not exactly what I want.
What I want is bascially the same as what Eclipse does with gdb. It spawns gdb as its child process and writes commands to the child process and retrieves gdb's output and displays or parses the captured output.
Oops, I have found a solution myself after 3 hours of struggling. The program runs fine, but I wonder if I am making minor mistakes. See my code below:
Code:
void test_pipe()
{
int pipe1[2];
int pipe2[2];
pid_t pid;
pipe(pipe1);
pipe(pipe2);
pid = fork();
if(pid == 0)
{
puts("In child process");
close(pipe1[1]);
dup2(pipe1[0], STDIN_FILENO);
close(pipe2[0]);
dup2(pipe2[1], STDOUT_FILENO);
puts("Spawning 'sort'");
execlp("sort", "sort", 0);
}
else
{
puts("In parent process");
close(pipe1[0]);
puts("Writing to child input");
FILE* fpw = fdopen(pipe1[1], "w");
srand(time(0));
puts("How many random numbers?");
char* str = safegets();
int n = atoi(str);
for(int i = 0; i < n; i++)
{
fprintf(fpw, "%d\n", rand());
}
fclose(fpw);
close(pipe1[1]);
puts("Reading child output");
close(pipe2[1]);
char buf[1000];
FILE* fpr = fdopen(pipe2[0], "r");
n = 0;
while(fgets(buf, 1000, fpr))
{
printf("#%d:%s", n, buf);
n++;
}
fclose(fpr);
close(pipe2[0]);
puts("End of child output");
puts("Waiting for child close");
waitpid(pid, 0, 0);
}
}
Last edited by neo_in_matrix; 09-15-2005 at 04:51 AM.
Secondly, in the parent, you first write a lot of stuff to the client process, and then proceed to read its output. In this case, this is fine, because 'sort' doesn't output anything before reading the last line of input.
Other programs (grep or cat being examples) may want to start writing output before reading the complete input. If these can't write output, they may stop reading input, causing your parent program to block on the writes. That would cause a deadlock.
Pipes do include some buffering, so this will only happen for "large" inputs and outputs, but it is still something worth considering.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.