1

Making a basic shell and I need to handle file redirection. Specifically I am stumped on how I can feed data into a program like sort for example from a file.

Something on the command line would look like this:

$ sort < test.txt

How do I accomplish this kind of functionality in my own mini shell made in C?

I thought that maybe sort read from stdin but I guess I can't really write the contents of a file to stdin due to the read only aspect so I'm wondering how I actually get this data into something like sort for example? I am currently using forks and then using execvp() to execute programs.

ComputerLocus
  • 3,448
  • 10
  • 47
  • 96
  • The shell opens the file (probably in the child process) and then arranges things with `dup2()` so that the file is connected to the `sort` process's standard input (and the original file descriptor for the file is closed). Then it runs the `sort` (assuming there was no other I/O redirection to deal with). Remember to handle open errors appropriately (and presumably you already handle failure to `exec*()`). There must be hundreds of questions on SO about I/O redirection in home-brew shells. – Jonathan Leffler Feb 16 '16 at 01:43
  • 1
    One common way is to use [`dup2`](http://man7.org/linux/man-pages/man2/dup.2.html). After the `fork` and before the `exec`, you open the file and then `dup2` its fd with `STDIN_FILENO` as the new fd. The target program only needs to read from stdin and doesn't need to know whether its coming from a file or from the terminal input. – kaylum Feb 16 '16 at 01:43
  • Maybe you can try `freopen()`? – nalzok Feb 16 '16 at 01:45
  • @kaylum For redirection from stdout to a file (carrot going other direction), I have been working with some modified bits from this answer: http://stackoverflow.com/a/14543455/1044984 . Should I basically be doing something like that again? – ComputerLocus Feb 16 '16 at 01:45

1 Answers1

3

You need to use freopen.

It works similarly to fopen. The first argument is the filename, the second argument is the mode, and the third argument is the file pointer to redirect. The return value is the new file pointer. So if you want to redirect stdin:

FILE *fp = freopen("input.txt", "r", stdin);

It returns a NULL pointer on failure, just like fopen.

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75