2016-11-01 2 views
0

Я пытаюсь написать код о процессе, который выполняет программы из $ PATH с помощью команды execlp(). (Она не должна быть командой execlp, но я нашел ее полезной для этот) Я достиг ожидаемого результата, но мне нужно запустить несколько команд. Более конкретно, я хочу, чтобы дочерний процесс запускал команду exec, затем родительский процесс печатал текст, указывающий, что он готов принять другую команду. Затем дочерний процесс запустит новую команду exec. Мой код заключается в следующем:цикл процесса в C

int main (int argc, char *argp[]) { 
pid_t progpid = fork(); // the fork command for the creation of the child process 
int status = 0; 
char com[256]; 

if (progpid < 0) // the check in case of failure 
    { 
    printf("PROGRAM ABORTED!"); 
    return 0; 
    } 
do 
    { 
    if (progpid == 0) // the child process 
     { 
     scanf("%s", com); 
     if (com == "exit") 
      { 
      exit(0); 
      } 
     else 
      { 
       execlp(com, com, NULL); 
      } 
     } 
else //the parent process 
    { 
     wait(&status); 
     printf("$"); 
    } 
}while (com != "exit"); 
return 0; 
} 

Ожидаемый результат:

<program which I input from keyboard> (for example : ls) 
<output of the program> 
$<next program> 
<output of the next program> 
. 
. 
. 
$exit 

Короче говоря, я хочу, чтобы запускать программы, пока я вхожу выхода, где она заканчивается, не делая ничего другого. Однако я получаю следующее:

<program> 
<output of program> 
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 

Он продолжает печатать $, пока не закрою его. Я новичок в процессах, поэтому пока не будьте слишком суровы относительно моего кода. Спасибо заранее!

+1

Логика вашей петли является ошибочной. Вы только создаете * один * дочерний процесс в начале программы. Вам нужно создать один дочерний процесс * за введенную команду *. –

ответ

1

Этот

if (com == "exit") 

должно быть

if (strcmp(com, "exit") == 0) 

Аналогично изменить состояние while, а также.

В С, строка сравнения выполнены с использованием strcmp(). == в вашем случае, просто сравнивает адрес com и адрес строкового литерала "exit". (В выражениях массив преобразуется в указатель на его первый элемент. Следовательно, сравнение «адрес» также см .: What is array decaying?).

Обратите внимание, что у вашего звонка execlp() есть проблема. NULL может быть определено как 0, и в этом случае execlp(), являясь вариационной функцией, может распознать его как последний аргумент. Я хотел бы предложить, чтобы изменить его на:

execlp(com, com, (char*)0); 

Вы также хотели бы проверить, если wait() не удалось или не проверив его код возврата.


Вот простой пример, основанный на вашем, с улучшенной проверкой ошибок.

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

int main (int argc, char *argp[]) { 

for(;;) { 
    char com[1024]; 
    printf("$ "); 
    fgets(com, sizeof com, stdin); 
    com[strcspn(com, "\n")] = 0; /* Remove if there's a newline at the end */ 

    if (strcmp(com, "exit") == 0) { 
     exit(0); 
    } 

    pid_t pid = fork(); 
    if (pid < 0) { 
     perror("fork"); 
     exit(1); 
    } 

    if (pid == 0) { /* child process */ 
     execlp(com, com, (char*)0); 
    } 

    int status; 
    int rc = wait(&status); 
    /* You can inspect 'status' for further info. */ 
    if (rc == -1) { 
     perror("wait"); 
     exit(1); 
    } 
} 

return 0; 
} 

Обратите внимание, что если вы хотите выполнить команды с аргументами, вам необходимо выполнить обработку аргументов.

+0

подождать не удалось. Я тестировал его без цикла while, и он работает. –

+0

Я просто говорю, что было бы хорошей проверкой кода возврата. Если есть какие-либо проблемы с исполнением 'com', вы должны знать об этом. –

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