2015-10-17 47 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