简体   繁体   中英

Wrong file descriptor while redirecting output of a comand to file

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

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM