2015-06-26 3 views
1

Я создаю массив строк, чтобы поместить атрибуты в команду (например, ls -l), но команда exec хочет массив символов, как я могу его решить? этот код должен создать дочерний элемент, который выполняет команду, выбранную путем ввода. У меня даже есть некоторые проблемы с wait(), когда pid != 0 .. Вы можете помочь мне закончить его? Большое спасибо.use exec с командой, введенной с клавиатуры

int main(void) { 

     char array[100]; 
     char character; 
     int i = 0; 
     char* point; 
     int j = 0; 

     printf ("Digit a string"); 
     printf ("\n"); 
     do { 
      character = getchar(); 
      array[i] = character; 
      i++; 
     } 
     while (character != '\n'); 
     array[i-1] = '\0'; 
     i = 0; 

     char* string[100]; 

     char *word = strtok(array, " ."); 
     while (word != NULL) { 
      printf("%s\n", word); 
      string[j] = word; 
      word = strtok(NULL, " ."); 

     } 

     printf ("\n"); 

    pid_t pid; 
    pid = fork(); 

     if (pid == -1) { 

     perror(""); 

    }else if (pid == 0) { 

     if (execlp(string, NULL) < 0) {  /* execute the command */ 

        exit(1); 
      } 
     else { 

     //.. wait until the child ends 
     wait(pid); 



     } 
    } 
    return; 
} 
+0

Почему бы вам не попробовать прочитать man-страницу для 'wait()'? Это должно легко ответить на часть вашего вопроса. – EOF

ответ

1

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

execlp("ls", "ls", "-l", NULL); 

Что у вас есть массив аргументов, так что вы хотите использовать один из вариантов v Exec. Вы можете найти все варианты here. Так что вы хотите сделать что-то больше, как это:

execvp(string[0], string); 

Обратите внимание, что сама команда является одним из аргументов, как в обоих примерах. Еще одна проблема с вашей программой заключается в том, что вы не увеличиваете j в своем цикле, где используете strtok. Также обратите внимание, что для execvp последний элемент массива должен быть NULL, поэтому exec знает, что он нашел последним аргументом. Наконец, вы не должны проверять возвращаемое значение любой из функций exec. Если возвращается exec, это означает, что произошла ошибка, иначе она никогда не вернется. errno устанавливается, когда exec не работает, поэтому вы можете это проверить. Для полноты поиска, секции исправленного кода ниже с комментариями:

char *word = strtok(array, " ."); 
j = 0; 
while (word != NULL) { 
    printf("%s\n", word); 
    string[j++] = word; // Increment j 
    word = strtok(NULL, " ."); 
} 
string[j] = NULL; // Make sure the array is NULL terminated 

А где вы называете exec

execvp(string[0], string); // You most likely want execvp, execv would work as 
          // well but that takes an entire path and not a filename 
fprintf(stderr, "Failed to exec"); // If the program reached this point we know exec failed 
exit(1); 

Позвольте мне объяснить, что он комментарий на execvp более подробно. Варианты exec с p в их имени принимают имя файла вместо пути. Эти варианты будут имитировать работу оболочки и использовать переменную окружения PATH для поиска двоичного файла. Поэтому, если вы делаете что-то вроде execlp("ls", "ls", "-l", NULL);, он будет работать, если у вас есть ls в одной из папок, указанной PATH. Если вы делаете execl("ls", "ls", "-l", NULL); (не отсутствие p), он не сработает, так как "ls" не является допустимым путем; вместо этого он должен был бы быть чем-то вроде "/usr/bin/ls". Какая версия вы хотите, что-то, что принимает имя файла или путь к файлу, зависит от вашего приложения.

+0

Большое вам спасибо! теперь код работает отлично! – Pino