Consider following source, reduced for simplicity
int main()
{
int d[2];
pipe(d);
if(fork())
{
close(1);
dup(d[1]);
execlp("ls", "ls", NULL);
}
else
{
close(0);
dup(d[0]);
execlp("cat", "cat", NULL);
}
}
So it creates a pipe and redirects the output from ls to cat.
It works perfectly fine, no problems. But change cat to more and bash breaks.
The symptoms are:
- you don’t see anything you type
- pressing “enter” shows up a new prompt, but not in a new line, but in the same one
- you can execute any command and see the output
resethelps fixing things up.
So there is a problem with input from keyboard, it is there, but is not visible.
Why is that?
UPDATE:
- the output from
ls | moreis equivalent to the output of my program moreprocess does not finish, it’s is orphaned byls- the only visible problem is with the state of the console after the parent process quits
- on some systems it does work like intended. E.g., on OpenSUSE I had no problems, on Kubuntu. I couldn’t find any information on what differences should I look for,
morebinaries are different on both systems
Because unlike
cat,moreis an interactive program that requires more thanstdin,stdoutandstderr— it requires a terminal, which your system call cannot provide. Try to runmorein a pipe or from a script and see what happens.Also note that
bashis not involved here at any stage, theexeclpfunction call replaces the current process by another one specified as an argument.