0

i'm trying to code the invoke function to call in my pseudoshell, but while the simple (one command) and pipe case work, when i try to redirect, it gives me a writing error saying that the file descriptor is wrong. the argv[] contains name and param of first command, and argv[] the same about second command;

int invoke(char *argv1[], char *argv2[], type_c tipo)
{
  int pid, pfd[2], fid;

  switch(tipo)
  {
    case(_SIMPLE):
      pid=fork();
      switch(pid) {
        case 0:
          execvp(argv1[0],argv1);
      }
      break;
    case(_PIPE):
      pipe(pfd);
      pid=fork();
      switch(pid) {
        case 0:
          close(1);
          dup(pfd[1]);
          close(pfd[0]); 
          close(pfd[1]);
          execvp(argv1[0],argv1);
        }
      pid=fork();
      switch(pid) {
        case 0:
          close(0);
          dup(pfd[0]);
          close(pfd[0]); 
          close(pfd[1]);
          execvp(argv2[0],argv2);
        }
        close(pfd[0]);
        close(pfd[1]); 
        break;
    case(_REDIRECT):
      pid=fork();
      switch(pid) {
        case 0:
          close(fileno(stdout));
          fid=open(argv2[0],O_CREAT|O_WRONLY);
          dup(fid);
          close(fid);
          execvp(argv1[0],argv1); 
        }
        break;          
      } 
      return pid; 
  }

to test it, in the main() function, i wrote this code:

char *argv[2][3];
argv[0][0]="ls";
argv[0][1]="-l";
argv[0][2]=NULL;
argv[1][0]="test";
argv[1][1]=NULL;  
pid=invoke(argv[0],argv[1],_REDIRECT); 

then, what can i do? :/ thanx to all in advance

Borgleader
  • 15,826
  • 5
  • 46
  • 62

1 Answers1

0

In case of _REDIRECT,

  • You are first closing the standard output. This implies that there is a free file-descriptor 1.
  • Now, you are opening the file, to which you want to send the output of the command. This directly opens on descriptor number 1.
  • Then, you are dup ing this new file-descriptor, which will open the same on descriptor 3(2 is for stderror).
  • Now, you are closing the fid which was previously on 1. The ls program then tries to print to the fd 1, which in this case is already closed, thus making it a bad-file descriptor.

There are two ways to solve this.

There is no need of the extra dup and your code works perfectly.

close(fileno(stdout));
int  fid=open(argv2[0],O_CREAT|O_WRONLY);
execvp(argv1[0],argv1);

To make our life easier there is another function dup2, which implicitly closes the target fd and makes it a copy of our fd.

int  fid=open(argv2[0],O_CREAT|O_WRONLY);
dup2(fid,1);
close(fid);
execvp(argv1[0],argv1);
nitish712
  • 19,504
  • 5
  • 26
  • 34