I am trying to to fork my c++ program and direct the parents output into the childs input, I am using pipe() and fork(). In the directory of the program there is a file called input.txt. Unfortunately the only output I get is "wc: stdin: read: Bad file descriptor". Does anyone know why this is? If so what am I doing wrong? Thanks
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#include <iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
int main(int argc, char *argv[]){
int pipes[2],pid,stdIn,stdOut;
stdIn = dup(0);
stdOut = dup(1);
pipe(pipes);
pid = fork();
if(pid == 0){
dup2(pipes[1],0);
close(pipes[1]);
execlp("wc","wc",NULL);
}
else{
dup2(pipes[0],1);
close(pipes[0]);
std::cout<<"input.txt"<<std::endl;
dup2(stdOut,0);
std::cout<<"parent done\n";
wait(NULL);
}
std::cout<<"after"<<std::endl;
return 0;
}
You have the pipe backwards, you have connected the write end of the pipe to the standard input of
wc
. You will need to close the write end of the pipe in both processes beforewc
will detect an end of file condition and terminate normally.You also incorrectly restore the original standard output to the standard input of the parent.
Furthermore
wc
will by default not interpret standard input as a list filenames and will therefore not readinput.txt
.There are several things that should be fixed in your program:
STDIN_FILENO
andSTDOUT_FILENO
instead of 0 and 1. This values may change on different platforms and you have also made a mistake which could probably be avoided if you've used names instead of value, e.g.dup2(stdOut,0);
duplicatedstdin
and you need to duplicatestdout
here.wc
read fromstdin
, you are then passing "input.txt" string to it - it will return stats for that string, not for the file. You could either fix it be opening a file descriptor for that file or usingexec*
withcat
.None of your calls the functions like
pipe()
orexeclp()
checks for failure. You should do it like that:You don't need
stdIn
variable.You will find fixed code below (it does not implement what I've described in the (5) though):
EDIT: As suggested in the comment to the other answer, you could simple use
xargs wc
to read stdint as file argument: