2017-03-02 44 views
0

我正在創建自己的Shell,並且通過使用我的is_background函數找到了一個&,我成功地獲得了在後臺運行的進程。它工作正常,直到我試圖實現標準輸出的重定向。 chk_if_output函數是過程函數中的一部分以及if語句if(out [0] == 1)。不知何故,實現重定向搞砸了我實現後臺進程的方式。如果我註釋掉重定向代碼,它會再次運行。每當我嘗試使用程序中的重定向代碼運行後臺進程時,我都會遇到分段錯誤,而且我不知道爲什麼。我沒有改變任何後臺進程代碼。更改不相關的代碼會導致分段錯誤。它爲什麼這樣做?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#define MAX_LINE 80 /* The maximum length command */ 

int is_background(char *args[], int size){ 
    int background = 0; 
    if (strcmp(args[size-1 ], "&") == 0){ 
     background = 1; 
     args[size-1] = NULL; 
    } 
    return background; 
} 

int * chk_if_output(char *args[], int size){ 
    int * out = malloc(2); 
    out[0] = 0; out[1] = 0; 
    for (int i = 0; i < size; i++){ 
     if (strcmp(args[i],">") == 0){ 
      out[0] = 1; 
      out[1] = i; 
      break; 
     } 
    } 
    return out; 
} 
void process(char *command, char *params[], int size){ 
    pid_t pid; 
    int background = is_background(params, size); 
    int *out = chk_if_output(params, size); 
    int fd; 
    int fd2; 
    pid = fork(); 
    if (pid < 0) { 
     fprintf(stderr, "Fork Failed\n"); 
    }else if (pid == 0) { 
     if(out[0] == 1){ 
      for (int i = out[1]; i < size; i++){ 
       params[i] = params[i+1]; 
      } 
      fd = open(params[out[1]-1],O_RDONLY,0); 
      dup2(fd,STDIN_FILENO); 
      close(fd); 
      fd2 = creat(params[out[1]],0644); 
      dup2(fd2,STDOUT_FILENO); 
      close(fd2); 
      out[0] = 0; 
      out[1] = 0;  
     } 
     execvp(command, params); 
    }else { 
     if(background == 1){ 
      waitpid(pid, NULL, 0); 
     } 
     background = 0; 
    } 
} 
int main(void) { 
    char *args[MAX_LINE/2 + 1]; /* command line arguments */ 
    int should_run = 1; /* flag to determine when to exit program */ 
    while (should_run) { 
     char *line; 
     char *endline; 
     printf("Leyden_osh>"); 

     fgets(line, MAX_LINE*sizeof line, stdin); 

     if((endline = strchr(line, '\n')) != NULL){ 
      *endline = '\0'; 
     } 

     if (strcmp((const char *)line,"exit") == 0){ 
      should_run = 0; 
     } 

     int i = 0; 
     args[i] = strtok(line, " "); 
     do{ 
      args[++i] = strtok(NULL, " "); 
     }while(args[i] != NULL); 

     process(args[0], args, i); 

     fflush(stdout); 

     return 0; 
    } 
+0

不,我從來沒有聽說過它現在。我會研究它。謝謝 – thefreeman

+1

@yantantphil我想出了valgrind!再次感謝。 – thefreeman

+0

您已經找到1/N問題。 'fgets'行是錯誤的,'line'是未初始化的,我不確定'MAX_LINE * sizeof line'的用意是什麼,但它沒有任何意義。 –

回答

0

在chk_if_output()函數中,循環中數組的最後一個元素爲NULL。

修復它通過循環到大小-1。

相關問題