Loyola College in Maryland

CS 702 Operating Systems
Fall 2003


Loyola College > Department of Computer Science > CS 702 > Examples and Lecture Notes > I/O Redirection

redirect.c

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>

/**
 * This runs the command "cat < redirect.c | wc > out"
 *
 * @author Jim Glenn
 * @version 0.1 11/18/2003
 */

int main(int argc, char** argv)
{
  int in, out, pipefd[2]; // file descriptors
  char *cat_args[] = {"cat", NULL}; // arguments for cat command
  char *wc_args[] = {"wc", NULL}; // arguments for wc command
  int status, i;
  pid_t first, second; // process ids

  // open the input file

  in = open("redirect.c", O_RDONLY);

  if (in < 0)
    {
      fprintf(stderr, "Error opening input file\n");
      exit(1);
    }

  // open the output file

  out = open("out", O_CREAT | O_WRONLY);

  if (out < 0)
    {
      fprintf(stderr, "Error opening output file\n");
      exit(1);
    }

  // create the pipe

  if (pipe(pipefd) != 0)
    {
      fprintf(stderr, "Error creating pipe.\n");
      exit(1);
    }

  // spawn the processes

  first = fork();
  
  if (first == 0)
    {
      // the child gets here

      dup2(in, 0); // replace stdin with the input file
      dup2(pipefd[1], 1); // replace stdout with output part of pipe
      close(pipefd[0]); // don't need other end of the pipe

      execvp("cat", cat_args);

      fprintf(stderr, "execvp for cat failed");
      exit(1);
    }
  else if (first > 0)
    {
      // the parent gets here

      second = fork();

      if (second == 0)
	{
	  // the second child gets here

	  dup2(pipefd[0], 0); // replace stdin with input part of pipe
	  dup2(out, 1); // replace stdout with the output file
	  close(pipefd[1]); // don't need other end of the pipe

	  execvp("wc", wc_args);
	  
	  fprintf(stderr, "execvp for wc failed");
	  exit(1);
	}
      else if (second > 0)
	{
	  // the parent gets here

	  close(in);
	  close(out);
	  close(pipefd[0]);
	  close(pipefd[1]);
	  
	  for (i = 0; i < 2; i++)
	    {
	      wait(&status);
	    }

	  printf("All done\n");
	}
      else
	{
	  fprintf(stderr, "Could not fork second child\n");
	  wait(&status);
	  exit(1);
	}
    }
  else
    {
      fprintf(stderr, "Could not fork first child\n");
      exit(1);
    }
}

This code can also be downloaded from the file redirect.c.