Vineeth Sai
Vineeth Sai

Reputation: 1557

Stdin redirection in custom shell in C?

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

Answers (1)

Rorschach
Rorschach

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

Related Questions