2014-11-15 5 views
0

Мне нужна помощь с простой оболочкой для класса, и я волнуюсь, я не совсем понимаю, как работает функция execvp().Простая оболочка Linux - execvp() не удалось

Оболочка не делает много, не поддерживает трубопроводы, перенаправление, сценарии или что-то подобное. Он читает только команду, читает в параметрах (с командой как опция [0]) и вилки.

Он работал несколько раз, а затем начал давать мне ошибки о том, что вы не можете найти команды. Другие подобные вопросы, заданные здесь, касались трубопроводов или перенаправления.

Пожалуйста, простите noobcode, это не очень, но я надеюсь, что это разборчивым:

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include <sys/types.h> 

#define OPT_AMT 10 

const size_t SIZE = 256; 
int i = 0; 
int o = 0; 

int main(void) { 

    // initializing data 

    int exit = 0; 
    char cwd[SIZE]; 
    char cmd[SIZE]; 
    char input[SIZE * OPT_AMT]; 
    char *opt[OPT_AMT]; 
    getcwd(cwd, SIZE); 

    // main loop 

    while (exit == 0) { 
     // reset everything 
     o = 1; 
     i = 0; 
     cmd[0] = "\0"; 
     while (i < OPT_AMT) { 
      opt[i++] = "\0"; 
     } 

     // get input 
     printf("%s $ ", cwd); 
     scanf("%s", cmd); 
     gets(input); 
     opt[0] = cmd; 

     char *t = strtok(input, " "); 
     while (t != NULL) { 
      opt[o++] = t; 
      t = strtok(NULL, " "); 
     } 

     // if exit, exit 
     if (strcmp(cmd, "exit") == 0) { 
      exit = 1; 
     } 
     // else fork and execute 
     else { 
      pid_t pID = fork(); 

      if (pID == 0) { // child process 
       execvp(cmd, opt); 
      } else if (pID < 0) { // failed to fork 
       printf("\nFailed to fork\n"); 
      } else { // parent process 
       wait(0); 
      } 
     } 
    } 

    // cleanup 

    printf("\nFinished! Exiting...\n"); 
    return 0; 
} 

Все, что явно не так? Недавно я добавил условие выхода и сброс массива параметров.

Кроме того, это мой первый вопрос, поэтому напомните мне о любых правилах, которые я, возможно, сломал.

+2

Не используйте 'gets()'. Это по своей сути небезопасно, и это даже не часть C. Вместо этого используйте 'fgets()' и не забудьте удалить символ новой строки в конце, если это необходимо. –

ответ

2

Для начала, это

cmd[0] = "\0"; 

должен быть

cmd[0] = '\0'; 

Слушайте предупреждения вашего компилятора.

Чтобы включить их, используйте опции -Wall -Wextra -pedantic (для gcc).


Кроме того, вы, возможно, лучше хотите initalise opt «s элементы не указывают на "ничего", то есть NULL но буквального "\0":

while (i < OPT_AMT) { 
     opt[i++] = NULL; 
    } 

, как execvp() требует opt быть NULL - (спасибо Paul за упоминание/формулировку соответствующего фона).


Также^2: Не используйте gets(), так как это зло, и даже не часть C стандарта больше. Вместо

gets(input); 

использования

fgets(input, sizeof input, stdin); 

gets() easyly давайте переливной пользователя по (вход) буфер передается. (Упоминание об этом пришло мне на ум без Paul, btw ... ;-))

+1

Действительно, 'execvp()' требует 'opt', чтобы быть списком строк с нулевым символом. –

+1

Спасибо, ребята, я внес изменения, но он дал мне ту же ошибку. Это имеет какое-то отношение к символу новой строки из fgets? – Will

+0

@Will: Вы бы очень помогли себе, если бы сделали несколько шагов, чтобы выяснить, что делает ваша программа, например 'printf()' значение 'cmd' и каждый элемент' opt', перед вызовом 'execvp()', чтобы вы действительно могли видеть, что вы ему передаете. Это будет отвечать на большинство этих типов вопросов. –

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

  • Нет связанных вопросов^_^