2014-12-15 2 views
1

Я пытаюсь реализовать базовую оболочку в C, но всякий раз, когда моя оболочка выполняет команду с помощью execvp(), она пропускает из цикла, я хочу, чтобы она осталась. Я подозреваю, что это потому что я не слишком хорошо знаком с execvp.execvp() не позволяет мне

Соответствующий код:

int main() 
{ 
    int nCmd = 1;     // Command number 
    char *line;      // Initial command line 
    token *list;     // Linked list of tokens 
    CMD *cmd;      // Parsed command 
    int process (CMD *); 

    for (; ;) { 

    printf ("(%d)$ ", nCmd);    // Prompt for command 
    fflush (stdout); 
    if ((line = getLine (stdin)) == NULL) // Read line 
     break;        // Break on end of file 

    list = lex (line); 
    // Lex line into tokens 
    free (line); 
    if (list == NULL) { 
     continue; 
    } else if (getenv ("DUMP_LIST")) {  // Dump token list only if 
     dumpList (list);     // environment variable set 
     printf ("\n"); 
    } 

    cmd = parse (list);      // Parsed command? 
    freeList (list); 
    if (cmd == NULL) { 
     continue; 
    } else if (getenv ("DUMP_TREE")) {  // Dump command tree only if 
     dumpTree (cmd, 0);     // environment variable set 
     printf ("\n"); 
    } 

    process (cmd);       // Execute command 

    freeCMD (cmd);       // Free associated storage 
    nCmd++;         // Adjust prompt 

    } 

    return EXIT_SUCCESS; 
} 

Вот соответствующие части «процесса»:

int process (CMD *cmdList) 
{ 
    if ((cmdList->nLocal)>0) 
    { 
     for (int i = 0; i<cmdList->nLocal; i++) 
     { 
      setenv(cmdList->locVar[i], cmdList->locVal[i], 0); 
     } 
    } 
    if (cmdList->type==SIMPLE) 
    { 
     execvp(cmdList->argv[0],cmdList->argv); 
    } 
    return 0; 
} 

Что происходит, что я получаю через первый процесс в основных годах для контура штрафа. Однако вместо чтения командной строки, как я хочу, после выполнения команды программа заканчивается. Как мне заставить его оставаться в цикле for?

+1

'execvp()' заменяет текущую программу новой программой. Чтобы продолжить обработку в исходной программе оболочки, вам понадобится 'fork()' then 'execvp()' в дочернем элементе. –

+0

Пожалуйста, ** RTFM ** здесь: http://man7.org/linux/man-pages/man3/exec.3.html (Первое предложение говорит все: "* Семейство функций exec() заменяет текущее образ процесса с новым образцом процесса. * ") – alk

ответ

2

execvp заменяет текущий процесс процессом, который вы просите запустить.

Чтобы создать дочерний процесс, необходимо выполнить fork и выполнить execvp из дочернего процесса. Таким образом, родитель будет еще жив и сможет обрабатывать больше пользовательских данных.

1

Семейство функций exec* уникально тем, что, как только программа достигает их, вся память процесса удаляется и перезаписывается с памятью процесса новой программы. Ваш код не выпрыгивает из цикла, цикл больше не существует.

Если вы хотите имитировать способ работы оболочки, вам придется использовать другой системный вызов для создания отдельного процесса, который может быть перезаписан: fork. Посмотрите его для получения дополнительной информации.

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