2016-11-20 1 views
0
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include <string.h> 
#include "command.h" 

int fd[10][2]; 
void closePipe(int fd_in,int fd_out); 
void execute_commands(struct command mycommands[], int no_commands){ 
    int i; 
    for(i=0;i<no_commands-1;i++){ 
     pipe(fd[i]); 
    } 
    i=0; 
    while(i<no_commands){ 
     if(i==0){ 
      if(no_commands==1){ 
       execute_command(mycommands[i].comm,mycommands[i].no_args,mycommands[i].args,-1,-2); 
      } 
      else{ 
       execute_command(mycommands[i].comm,mycommands[i].no_args,mycommands[i].args,-1,0); 
      } 
     } 
     else if(i==no_commands-1){ 
      execute_command(mycommands[i].comm,mycommands[i].no_args,mycommands[i].args,no_commands-2,-1); 
     } 
     else{ 
      execute_command(mycommands[i].comm,mycommands[i].no_args,mycommands[i].args,i-1,i); 
     } 
     i++; 
    } 
    i=0; 
    for(i=0;i<no_commands-1;i++){ 
     close(fd[i][0]); 
     close(fd[i][1]); 
    } 
    for(int i=0;i<=no_commands;i++){ 
     wait(NULL); 
    } 

} 

int execute_command(char *command, int argc, char *args[], int fd_in, int fd_out) 
{ 
    pid_t pid = fork(); 
    if(pid==0){ 
     int out = dup(1); 
     if(fd_in==-1){ 
      if(fd_out!=-2){ 
       close(1); 
       dup(fd[fd_out][1]); 
       close(fd[fd_out][0]); 
      } 
     } 
     else if(fd_out==-1){ 
      closePipe(fd_in,fd_in); 
      close(0); 
      close(fd[fd_in][1]); 
      dup(fd[fd_in][0]); 
     } 
     else{ 
      closePipe(fd_in,fd_in); 
      close(fd[fd_in][1]); 
      close(fd[fd_out][0]); 
      close(0); 
      dup(fd[fd_in][0]); 
      close(1); 
      dup(fd[fd_out][1]); 

     } 
     if(execvp(command,args)==-1){ 
      close(fd_out); 
      dup2(out,1); 
      printf("bash: %s: command not found...\n",command); 
     } 
     exit(0); 
    } 
    else{ 
     /*IF I INCLUDE WAIT(NULL) OR ANY WAIT FAMILY, EXECVP DOES NOT FINISH EXECUTING 
      THIS CODE WORKS PERFECTLY NOW, BUT I NEED TO STOP THE PROGRAM IF THE USER ENTERS WRONG COMMAND WITH 
      AN ERROR MESSAGE. SO I NEED TO INCLUDE WAIT HERE. 
     */ 
    } 
    return 0; 
} 

void closePipe(int fd_in,int fd_out){ 
    int i=-1; 
    if(fd_in<fd_out) 
     i=fd_in-1; 
    else 
     i = fd_out-1; 

    int k=0; 
    while(k<=i){ 
     close(fd[k][0]);close(fd[k][1]); 
     k++; 
    } 
} 

mycommands [] struct array содержит команды и аргументы, которые должны быть выполнены. Я сделал все, кроме одной части. Если одна из команд недействительна, мне нужно вывести сообщение об ошибке, проблема в том, что я ставил wait (NULL) или любую команду wait в else-части execute_command (т.е. родительский процесс), программа не работает для 2 команд или больше команд, по какой-то причине execvp не прекращает выполнение. Он работает, когда я не добавляю wait (NULL). Но так как мне нужно остановить программу, если одна из команд недействительна, мне нужно использовать wait (& status) в другой части функции execute_command.Linux Shell в C: Execvp не завершает выполнение, когда wait добавлен к родительскому

Кто-то, пожалуйста, помогите. Я пытаюсь решить это в течение последних 2-3 часов.

+0

Правильного отступ и промежутки между * действительно * важной для удобства чтения. Я предлагаю помещать это в хороший редактор, например [Sublime Text] (http://www.sublimetext.com/) и правильно ли он отступы. – Schwern

+0

См. Http://stackoverflow.com/help/mcve - хороший вопрос включает * наименьший * возможный объем кода, который можно использовать для воспроизведения той же проблемы. В этом случае это означает в идеале только основную функцию с fork(), execve() и wait() с аргументами & c. жестко закодированы, насколько это возможно, хотя и достаточно полно, чтобы запускать и демонстрировать проблему. –

+0

Я сделал код более удобочитаемым. –

ответ

0

Попробуйте удалить этот блок

for(int i=0;i<=no_commands;i++){ 
    wait(NULL); 
} 

И добавить wait(NULL) к другому части

else{ 
    /*IF I INCLUDE WAIT(NULL) OR ANY WAIT FAMILY, EXECVP DOES NOT FINISH EXECUTING 
     THIS CODE WORKS PERFECTLY NOW, BUT I NEED TO STOP THE PROGRAM IF THE USER ENTERS WRONG COMMAND WITH 
     AN ERROR MESSAGE. SO I NEED TO INCLUDE WAIT HERE. 
    */ 
    wait(NULL); 
} 
+0

Я сделал это, все еще работаю –

+0

@NihalAr проверил ваши команды вручную на терминале, и они уходят, как ожидалось? – cshu

+0

да его работа как ожидалось. –

Смежные вопросы