2015-10-17 23 views
0

我一直在試圖拿起C來完成一項說明創建C shell的作業任務。一個要求是所有的命令都應該從子進程執行。這個問題似乎是我的子進程過早死去了,我從來沒有去過實際執行命令的那部分代碼。我的代碼:Linux C Shell,子進程引發的分段錯誤

parseCommand.h

char *parseCommand(char str[]) { 
    char * token; 
    //get size of the input array. divide memory amount allocated to array by the size of the 1st element (which should be representative of other elements) 
    size_t n = sizeof(str)/sizeof(str[0]); 
    char *args = malloc(n); 
    printf("Splitting string \"%s\" into tokens:\n", str); 
    token = strtok(str, " \n"); 
    int i = 0; 
    while (token != NULL) { 
     printf(":: %s\n", token); 
     args[i++] = token; 
     token = strtok(NULL, " \n"); 
    } 
    printf("after while loop"); 
    args[i]=(char *) 0; 
    return args; 

} 

的main.c

//I probably don't need all these 
#include<stdio.h> 
#include<string.h> 
#include<stdlib.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <string.h> 

//Custom Libraries 
#include "parseCommand.h" 

char *parseCommand(char str[]); 

int main() { 

    char path[10] = "/bin/";//path to bash scripts 
    int should_run = 1; 
    while (should_run) { 
     printf("yazan_shell>> "); 
     fflush(stdout); //force the prompt to the output immediately 
     char *cmdStr = (char *)malloc(40); //allocate space for array 
     fgets(&cmdStr, 40, stdin); //save user input to cmdStr 
     pid_t pid = fork(); //create 
     if (pid == 0) { 
      printf("==> Child received: %s command. Executing...\n", &cmdStr); 
      char *cmd = parseCommand(&cmdStr);//split user input by space 
      printf("cmd: %s", &cmd); 
      execvp(strcat(path, cmd[0]), cmd);//excecute the input cmd 
     } else { 
      int returnStatus; 
      waitpid(pid, &returnStatus, 0); //parent waits for child process 
      printf("==> Parent is silent!! PID: %d\n", pid); 
      should_run = 0; 
     } 
     free(cmdStr); //deallocate cmdStr 
    } 
} 

輸出1

yazan_shell>> ls -l 
==> Child received: ls -l 
command. Executing... 
Splitting string "ls -l 
" into tokens: 
:: ls 
:: -l 
==> Parent is silent!! PID: 5500 

RUN FINISHED; Segmentation fault; core dumped; real time: 3s; user: 0ms; system: 0ms 

我剛開始LEA在幾天前C,但我谷歌在C中的分割錯誤,似乎我要麼解引用非初始化指針或嘗試訪問釋放內存。所以,我想註釋掉

free(cmdStr); 

行,然後輸出的樣子:

yazan_shell>> ls -l 
==> Child received: ls -l 
command. Executing... 
Splitting string "ls -l 
" into tokens: 
:: ls 
:: -l 
==> Parent is silent!! PID: 5601 

RUN FINISHED; exit value 33; real time: 1s; user: 0ms; system: 0ms 

我也試過在移動在while循環print語句parseCommand.h但輸出似乎不改變。我問過一些可用的C++教授,但他們中沒有人能夠查明錯誤。有人能夠給我一些關於我的錯誤的指示(hehe)嗎?

非常感謝您提前!

+1

啓用更多的編譯器警告。 'fgets(&cmdStr,...)'無效。將'&cmdStr'傳遞給'printf''%s'是無效的。 'strcat(...,cmd [0])'無效。 – melpomene

+1

'args [i ++] = token'無效。 'args [i] =(char *)...'無效。基本上,您的代碼中的每個指針操作都是錯誤的。 – melpomene

+1

如果您使用的是gcc,您應該(至少)使用以下內容:'gcc -Wall -Wextra -pedantic'並修復所有警告。 – melpomene

回答

1

有幾個問題 -

main -

char *cmdStr = (char *)malloc(40); // don't cast it 
fgets(&cmdStr, 40, stdin);  // don't pass address of cmdStr it is already a char * 

只是,這是好的 -

char *cmdStr =malloc(40); 
fgets(cmdStr, 40, stdin); 

2.也是這裏 -

char *cmd = parseCommand(&cmdStr);//split user input by space 
printf("cmd: %s", &cmd);  //cmd is already a char * don't pass its address 

寫這樣的 -

printf("cmd: %s", cmd); 

在你的函數char *parseCommand(char str[])當你計算元素的數量 -

size_t n = sizeof(str)/sizeof(str[0]); 

預期這不會工作。所以計算nmain然後傳遞給你的函數

+0

我遵循你的建議,它似乎沒有解決輸出中的任何問題。孩子仍然過早死亡 – YazanLpizra