I have an assignment where I need to create a shell in C. One of the specifications is to implement input redirection when the redirection symbol is entered ('<'). Then I am attempting to read the input from stdin using fgets. After the input is read, the saved_stdin is restored to the normal input stream.
However, on the first time the input is redirected, it works perfectly. Then, on the times after that, nothing is read from stdin. I have tried debugging several times but cannot find my error. Would really appreciate your help!
My code is below so that you can be able to reproduce the error, and help me correct my mistakes. Also, make sure to create a file named text.txt in the directory where you're running the program. Contents of text.txt:
hello, how are you?
Note that the code is extremely simplified and I am simply using hard-coded arguments. In my actual implementation, input is being given by the user (I am 100% sure that there is nothing wrong with receiving the input).
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#define MAX_ARG_LENGTH 100
int redir_in(char **args, int in_pos);
void echo();
void reset();
// Global Variables
int saved_stdin;
bool changed_in;
int main(void)
{
// sample arguments (args)
char *args[MAX_ARG_LENGTH] = {"echo", "<", "text.txt"};
// position of '<'
int pos = 1;
printf("output 1: ");
if(redir_in(args, pos) == 0){
echo();
reset();
}
printf("\noutput 2: ");
if(redir_in(args, pos) == 0){
echo();
reset();
}
printf("\nexiting...\n");
return 0;
}
void echo()
{
char line[MAX_ARG_LENGTH];
while(fgets(line, MAX_ARG_LENGTH, stdin) != NULL)
printf("%s", line);
}
// args is an array of inputted string arguments, in_pos is the index
// of '<' in the array
int redir_in(char **args, int in_pos)
{
char *file_name;
file_name = args[in_pos + 1];
int fd;
fd = open(file_name, O_RDONLY, S_IRUSR);
if (fd < 0)
return -1;
saved_stdin = dup(0);
dup2(fd, STDIN_FILENO);
close(fd);
changed_in = true;
return 0;
}
void reset()
{
if(changed_in){
dup2(saved_stdin, 0);
close(saved_stdin);
changed_in = false;
}
}
Expected output:
output 1: hello, how are you?
output 2: hello, how are you?
exiting...
Output I'm getting:
output 1: hello, how are you?
output 2:
exiting...