I have the following program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <sys/wait.h>
int main()
{
int p[2];
char *argv[2];
argv[0] = "wc";
argv[1] = "-w";
argv[2] = NULL;
pipe(p);
if (fork() == 0)
{
close(0);
dup(p[0]);
close(p[0]);
close(p[1]);
execvp(argv[0], argv);
}
else
{
close(p[0]);
write(p[1], "hello world\n", 12);
}
fprintf(stdout, "hello world\n");
}
And when I run it:
$ gcc a.c
$ ./a.out
I got the following:
hello world
$ 2
_ // the cursor is flickering here
After I type Enter
, the program exit. What is the reason for this? In addition, if I exchange the content in the parent process and child process like this:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <sys/wait.h>
int main()
{
int p[2];
char *argv[2];
argv[0] = "wc";
argv[1] = "-w";
argv[2] = NULL;
pipe(p);
if (fork() == 0)
{
close(p[0]);
write(p[1], "hello world\n", 12);
}
else
{
close(0);
dup(p[0]);
close(p[0]);
close(p[1]);
execvp(argv[0], argv);
}
fprintf(stdout, "hello world\n");
}
I got the output as I expect:
hello world
2
$
The program has exited and is ready to get next command. What's the problem of the first program?
If you look very carefully at your output, you'll see that your program has exited:
hello world
$ 2
_ // the cursor is flickering here
See how the $
is printed? This is your shell waiting for input as usual. By pressing enter
you've just input a blank command to your shell and obtained a second $
prompt.
What's the 2
doing there? That's wc
's output. Your program isn't actually waiting for wc
to exit. This means that your program exits before wc
does, so the shell resumes, prints its prompt, and only then does wc
exit and print 2
.
To fix, you'll probably want to add some kind of wait
call to wait for the child process in the parent.