• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 666
  • Last Modified:

Close stdin and stdout to use redirection with a unix shell

I am creating my own shell to work as a unix shell (bash or other). I have gotten it to work with things like ls and pwd using execvp(), but I also want to be able to handle redirection like ls > out.txt. I think that I have to first close stdout and open out.txt before i call fork, but using this code:
if (!strcmp(command[i], ">"))
I get error: STDOUT' undeclared (first use in this function).
I also tried stdout, but got the same error. Am I missing a header?
Hope someone can help me
  • 2
1 Solution
I think most software at the shell level just uses 0, 1, and 2 for the stdin, stdout, and stderr descriptor numbers.  I wouldn't feel bad about using the bare numbers since that convention is so ingrained in UNIX tradition.

But, if you really want to use a #defined constant, STDOUT_FILENO and friends are defined in <unistd.h>.

I think you might be wrong in the sequence of events for redirecting output into a file.  I believe it usually goes:
int pid = fork();
if (pid) { /* parent */
    don't mess with file descriptors
    wait() for child to finish
} else { /* child */
    close all open descriptors except 0,1,2
    close & open file descriptors 0,1,2 to handle redirected input and/or output
    exec() the command
Instead of closing 'stdout', why not using

   /* Reassign "stdout" to "out.txt": */
   stream = freopen( "out.txt", "w", stdout );
In my experience, shells don't usually touch FILE * i/o, and stay in the realm of file descriptors.  The idea behind freopen() can be implemented by using open() and dup2().
v_wall78Author Commented:
I figured out how to do it:

if (!strcmp(command[i], ">"))  {                                                                   // if input redirection
if ((in = open(command[i+1], O_RDONLY)) == -1) {                                      // open input file specified
      fprintf(stderr, "Input file specified could not be opened.\n");
       return -1; }
dup2 (in, fileno(stdin)); }                                                                            // change fileid 0 from stdin to the file specified by user

if (!strcmp(command[i], ">"))  {                                                                  // if output redirection
   if ((out = open(command[i+1], O_WRONLY|O_CREAT,0644)) == -1) {        // open or create output file specified
       fprintf(stderr, "Output file specified could not be opened.\n");
        return -1; }
dup2 (out, fileno(stdout)); }

Thanks guys

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now