Reputation: 1557
So, Basically, I'm creating my own shell in C, which can handle redirection. My stdout redirection is working but my stdin redirection does not work.
I'm trying to redirect stdin for Examples:
hw9> cat < out.txt
hw9> grep if < out.txt
My code:
if(strcmp(token[i],"<")==0)
{
token[i]=NULL;
int fd0;
if ((fd0 = open(token[i + 1], O_RDONLY)) < 0)
{
perror("Couldn't open input file");
exit(0);
}
close(0);
// dup2() copies content of fdo in input of preceeding file
dup2(fd0, 0); // STDIN_FILENO here can be replaced by 0
close(fd0); // necessary
}
This is my if block to check and perform stdin redirection but this doesn't seem to work.
The expected output for cat out.txt
is "helloo"
and that should be the same output for cat < out.txt
because the redirection will correspond to cat out.txt
. But cat < out.txt
doesn't give any output. The content of the file out.txt
is "helloo"
.
hw9> cat out.txt
Tokens:
[0] 'cat'
[1] 'out.txt'
"helloo"
hw9> cat < out.txt
Tokens:
[0] 'cat'
[1] '<'
[2] 'out.txt'
hw9>
As you can see, the first call provides the correct output as expected but the second call does not prove any output. Let me know if you need any more information. I tried multiple other ways, but nothing seems to work. Thanks in advance!
Edit: I got it to work! My mistake was calling the execvp()
outside the if block. I called it inside the if-block, and it seems to work! Thanks guys!
Final code:
if(strcmp(token[i],"<")==0)
{
token[i]=NULL;
int fd0;
if ((fd0 = open(token[i + 1], O_RDONLY)) < 0)
{
perror("Couldn't open input file");
exit(0);
}
close(0);
// dup2() copies content of fdo in input of preceeding file
dup2(fd0, 0); // STDIN_FILENO here can be replaced by 0
close(fd0); // necessary
execvp(*token, token);
perror("execvp");
}
Upvotes: 1
Views: 582
Reputation: 32426
There isn't anything wrong with your code as far as I can tell. There error probably lies elsewhere, perhaps where you are calling exec
. For example,
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
int fd0;
char *args[3] = { NULL };
args[0] = argv[1];
if (strcmp(argv[2], "<") == 0) {
if ((fd0 = open(argv[3], O_RDONLY)) < 0) {
perror("open");
exit(1);
}
dup2(fd0, STDIN_FILENO);
close(fd0);
execvp(argv[1], args);
} else {
args[1] = argv[2];
execvp(argv[1], args);
}
return EXIT_SUCCESS;
}
Calling the above test.out
I see the expected output, calling without redirection,
./test.out cat test.c
And with redirection (quoted since the shell would do its own redirection)
./test.out cat '<' test.c
Upvotes: 2