2015-10-17 2 views
0

Я пытался подобрать C для задания домашней работы, которое говорит о создании оболочки C. Одним из требований является то, что все команды должны выполняться из дочернего процесса. Проблема заключается в том, что мой дочерний процесс умирает слишком рано, и я никогда не добираюсь до той части кода, которая фактически выполняет эту команду. Мой код: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 

Я только начал Леа rning C пару дней назад, но я ошибками сегментации google'd в 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 

Я также попытался переместить оператор печати в цикле в то время как в parseCommand.h но выход, кажется, также не меняются. Я попросил нескольких профессоров C++, которые были доступны, но ни один из них не смог определить ошибку (-ы). Кто-нибудь здесь может дать мне несколько указателей (хе-хе) о моей ошибке?

спасибо, что заблаговременно!

+1

Включите дополнительные предупреждения компилятора. 'fgets (& cmdStr, ...)' неверно. Передача '& cmdStr'' 'printf''% s' неверна. 'strcat (..., cmd [0])' недействителен. – melpomene

+1

'args [i ++] = токен' недействителен. 'args [i] = (char *) ...' недействителен. В принципе, каждая операция указателя в коде неправильная. – melpomene

+1

Если вы используете gcc, вы должны (как минимум) использовать следующее: 'gcc -Wall -Wextra -pedantic' и исправить все предупреждения. – melpomene

ответ

1

Есть несколько проблем -

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

3. В функции char *parseCommand(char str[]) при расчете количества элементов -

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

это не будет работать, как ожидалось. Итак, вычислите n в main, а затем передайте его функции

+0

Я следил за вашими советами и, похоже, ничего не исправить в результатах. Ребенок все еще умирает преждевременно – YazanLpizra

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