Piping and redirecting in my own simple shell

By : rsa
Source: Stackoverflow.com
Question!

I have written the beginning of a simple shell and so far 'ls' works fine. I have this code written for forking and execing. However, when I try to use my redirects, I'm getting the error "cannot access '>': No such file or directory. How do I make these operators read as such?

int startProcess (StringArray sa)
{
  int pid; 
  int status;
  int fd1;
  int fd2; 
  int current_in;
  int current_out; 

  switch( pid = fork()){
 case -1://This is an error 
   perror("Failure of child.");
   return 1;
 case 0: // This is the child
   execvp(sa[0], sa);

   for (int i = 0; i < strlen(sa); i++){
     if (sa[i] == '|'){
     }
     if (sa[i] == '>'){
       fd1 = creat(sa[i-1], 0644);
       dup2(fd1, STDOUT_FILENO);
       close(fd1); 
     }
     if(sa[i] == '<'){
       fd2 = open(sa[i-1], O_RDONLY, 0);
       dup2(fd2, STDIN_FILENO);
       close(fd2);
     }
   }

   perror(sa[0]);
   printf("Could not execute '%s'\n", sa[0]);
   exit(1);
 default:// This is the parent 
   wait(&status);
   return (status == 0) ? 0: 1;
  }
}
By : rsa


Answers
Please have a look at this example that does a redirect to a file.

#include <zconf.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>;

int startProcess(char *sa[]) {
    int pid;
    int status;
    int fd1;
    int fd2;
    int current_in;
    int current_out;
    switch (pid = fork()) {
        case -1://This is an error
            perror("Failure of child.");
            return 1;
        case 0: // This is the child
            fd2 = open("output", O_WRONLY | O_CREAT, 0666);
            dup2(fd2, STDOUT_FILENO);
            close(fd2);
            execvp(sa[0], sa);
            perror(sa[0]);
            printf("Could not execute '%s'\n", sa[0]);
            exit(1);
        default:// This is the parent
            wait(&status);
            return (status == 0) ? 0 : 1;
    }
}

int main(int argc, const char *argv[]) {

    char *ch[] = {"ls", "-l", NULL};
    startProcess(ch);
    return 0;
}

Test

[email protected] ~/C/twodec> ls
a.out*  CMakeLists.txt  data.txt  in2  integers.txt  main.c  target.txt
[email protected] ~/C/twodec> gcc main.c 
[email protected] ~/C/twodec> ./a.out 
[email protected] ~/C/twodec> ls
a.out*  CMakeLists.txt  data.txt  in2  integers.txt  main.c  output  target.txt
[email protected] ~/C/twodec> more output 
total 36
-rwxrwxr-x 1 dac dac 9104 sep 12 04:29 a.out
-rw-rw-r-- 1 dac dac  177 sep 11 17:56 CMakeLists.txt
-rw-rw-r-- 1 dac dac  336 sep 11 15:58 data.txt
-rw-rw-r-- 1 dac dac   44 jul 28 05:34 in2
-rw-rw-r-- 1 dac dac   99 sep 10 15:08 integers.txt
-rw-rw-r-- 1 dac dac 1351 sep 12 04:29 main.c
-rw-rw-r-- 1 dac dac    0 sep 12 04:29 output
-rw-rw-r-- 1 dac dac   74 jul  5 08:22 target.txt


This video can help you solving your question :)
By: admin