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

Добрый вечер

Я нашел несколько похожих вопросов, но ничего, что было бы достаточно для этого конкретного вопроса.

Я разветвляю дочерний процесс и пытаюсь вызвать execvp для запуска простой программы, которая выводит 3 символа на стандартный вывод. Имя запускаемой программы исходит от пользователя.

По какой-то причине каждый вызов execvp терпит неудачу для simpleO:

Я компилирую файл simpleO.c в simpleO, а затем компилирую и запускаю fork.c. Я набираю simpleO в приглашении, когда меня просят попытаться запустить, но каждый раз я получаю сообщение об ошибке. Вот код.

Сообщение об ошибке, напечатанное perror: «Нет такого файла или каталога».

--

fork.c

#include <stdio.h>
#include <unistd.h>/*fork, exec*/
#include <errno.h>/*errno*/
#include <string.h> /*strerror*/
#include <stdlib.h>/*EXIT_FAILURE*/

#define BUFFERSIZE 100

int main(int argc, char *argv[]){
int i = 0;
pid_t pid;
int status;
char buffer[BUFFERSIZE];

fgets(buffer, BUFFERSIZE, stdin);

argv[0] = strtok(buffer, " ");
while (buffer[i] != '\0') {/*analyze each char*/
    if (buffer[i] == ' ')/*based on how many spaces there are*/
        argv[i] = strtok(NULL, " ");/*tokenize, populate argv*/
    i++;
}  

if((pid = fork()) == -1){
    fprintf(stderr, "fork error: %s\n", strerror(errno));
    return EXIT_FAILURE;}
else if (pid==0) {
    int e = execvp(argv[0],argv);
    if (e==-1) {
        perror("Exec failed");
        printf("Process %s\n",argv[0]);
        perror("Process did not run");
        exit(1);
    }
}
else{
    wait(&status);}
return 0;
}

--

простой O.c

#include <stdio.h>
int main(int argc, char **argv){
    printf("%c",'c');
    printf("%c",'2');
    printf("%c",'1');
return 0;
}

Addl ref: perror печатает «Нет такого файла или каталога»


person ian_wytiam    schedule 08.03.2017    source источник
comment
Та же проблема возникает при вводе ./simpleO   -  person ian_wytiam    schedule 08.03.2017
comment
Вы могли бы с пользой добавить сообщение, напечатанное perror, чтобы те из нас, у кого нет экстрасенсорных способностей, могли видеть то, что видите вы.   -  person rici    schedule 08.03.2017
comment
Обновлено для магглов   -  person ian_wytiam    schedule 08.03.2017
comment
Не могли бы вы убедиться, что ваш код компилируется перед публикацией? Например, array_of_pointers не объявлен.   -  person kaylum    schedule 08.03.2017
comment
Обновлено, потому что я магл и забыл удалить array_of_pointers   -  person ian_wytiam    schedule 08.03.2017
comment
Кроме того, этот цикл while просто тарабарщина. Где i объявляется и инициализируется? Как вы думаете, почему его значение каким-либо образом влияет на вызов strtok? И почему вы думаете, что argv достаточно большой, чтобы вместить все слова в вашей строке ввода, даже если вам удастся их разделить?   -  person rici    schedule 08.03.2017
comment
Хорошие вопросы. Я не копировал и не вставлял весь код, поэтому было несколько несоответствий. Теперь он должен нормально компилироваться   -  person ian_wytiam    schedule 08.03.2017


Ответы (1)


Хорошо, слушайте: ключевой урок программирования состоит в том, что когда сообщение об ошибке говорит вам что-то, вы должны этому верить. Итак, ваша программа говорит «нет такого файла или каталога», и это означает, что файл, который вы пытаетесь запустить, не существует по тому пути, который вы пытаетесь использовать.

Теперь вы знаете, что это не путь по умолчанию, поэтому попробуйте использовать абсолютный путь к исполняемому файлу. Теперь, учитывая все остальное, я предлагаю вам написать очень простую программу на C, которая ничего не делает, кроме как пытается разветвить/выполнить вашу дочернюю программу. Никакого вектора argv или чего-то еще, просто fork, а затем execvp в дочернем элементе с путем к исполняемому файлу в абсолютной части.

person Charlie Martin    schedule 08.03.2017
comment
БИНГО! Теперь вы знаете, в чем проблема. Вот ваш следующий шаг: используйте getcwd() и узнайте, какой настоящий текущий каталог. затем вы можете либо использовать setcwd(), чтобы изменить то, что вы думаете, должна быть текущая директория, либо вы можете выяснить, как вычислить соответствующий путь без его жесткого кодирования. - person Charlie Martin; 08.03.2017
comment
Ах, а затем strcat /programname в конце этого абсолютного пути? Спасибо за ответ кстати - person ian_wytiam; 08.03.2017
comment
Ключевой урок программирования заключается в том, что когда сообщение об ошибке говорит вам что-то, вы должны этому верить. Я заставлю своих учеников выучить это наизусть и повторять в начале и в конце каждого урока... - person DYZ; 08.03.2017
comment
Вау, кажется, я нашел это. В конце моего буфера была новая строка (из fgets()), и она искажала абсолютный путь. Большое спасибо, Чарли! - person ian_wytiam; 08.03.2017
comment
Ключевой урок программирования заключается в том, что когда сообщение об ошибке говорит вам что-то, вы должны этому верить. Конечно. Просто пришлось удалить / в конце абсолютного пути. О! - person ian_wytiam; 08.03.2017
comment
@DYZ, просто удивительно, как часто мне приходится давать этот урок начинающим программистам и даже некоторым довольно опытным программистам. Еще один из этих уроков заключается в том, что вероятность › 0,995 того, что это не ошибка компилятора. - person Charlie Martin; 08.03.2017
comment
@ian_wytiam, добро пожаловать и не беспокойтесь об этом. Когда-нибудь я расскажу вам о времени, которое я потратил два дня, пытаясь понять, почему сделанные мной изменения не повлияли на результаты программы, прежде чем я понял, что это не компилируется, а библиотечная система просто использует старый исполняемый файл. (Это было во времена перфокарт.) - person Charlie Martin; 08.03.2017