I'm trying to run the command "wc -l << END
" using execvp, so I'm parsing the command and runing execvp with "wc -l
" but then it goes into an infinite loop.
How can I make it work so it stops when it finds the keyword (in this case END)?
- I have to use execvp
- the command comes from a user input that in this case is "
wc -l << END
"
edit
Here is my code (won't help much but can give some background)[the code for the here-doc is in the last else statement]:
redirect(int proc, char * input){
char * comm;
int proc2;
int append = 0;
if(proc == 1){ //in
comm = strsep(&input, "<");
proc2 = check(input);
}
else{ //out
comm = strsep(&input, ">");
proc2 = check(input);
if(proc2 == 2){ //append
strsep(&input, ">");
append = 1;
}
}
if(proc2 == 0 || append == 1){ //only one redirection
if(proc == 1){ //in
input = trim(input);
int fd = open(input, O_RDWR);
close(0);
dup2(fd, 0);
close(fd);
comm = trim(comm);
char ** words = parse(comm);
if(!execvp(words[0], words)){ /*exec failed */
exit(1);
}
}
else{ //out
input = trim(input);
int fd;
if(append == 0){ //create
fd = open(input, O_CREAT | O_RDWR | O_TRUNC,
S_IRUSR | S_IWUSR);
}
else{ //append
fd = open(input, O_CREAT | O_RDWR | O_APPEND,
S_IRUSR | S_IWUSR);
}
dup2(fd, 1);
close(fd);
comm = trim(comm);
char ** words = parse(comm);
if(!execvp(words[0], words)){ /*exec failed */
exit(1);
}
}
}
else{ //more than one redirection/pipe
if(proc == proc2){ //here-doc
strsep(&input, "<");
input = trim(input);
}
}
}
A solution would be to store the user input into a temp file and then pass the temp file as stdin but I wanted to know if there is a better way to do it.
Rather than using a temp file and pointing the child's stdin at it, you can feed the input to the child through a pipe, from either the parent or another child process. The parent or second child process would then take care of reading the input, watching for the end of input marker, and passing the data along to your (original) child process.
The following example shows how to use a pipe and a second child process to read stdin, watch for an end-of-input marker, and pass the input through to the original child process until it's found. The example omits error checking (which you should add), and uses hard-coded values for the command to run and the end of input marker. Note that it's important that the write end of the pipe be closed in the parent so that the command will see it's stdin closed after the input reader exits.