Возникли проблемы с execvp - PullRequest
0 голосов
/ 05 марта 2019

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

Вот код для функции:

int extern_process(char *arg[]){
    pid_t pid;
    int errnum, ifFail;
    printf("i%si\n",arg[0]);
    pid = fork();

    if(pid == -1){
        errnum = errno;
        fprintf(stderr,"Error: fork %s", strerror(errnum));
        return FAIL;
    } else if(pid == 0){
        ifFail = execvp(arg[0],arg);
        if(ifFail < 0){
            errnum = errno;
            fprintf(stderr,"Error: exec %s", strerror(errnum));
            return FAIL;
        }
    } else {
        pid = wait(NULL);
    }
    return SUCCESS;
}

Вот код для функции анализа на всякий случай:

void parse_cmd(char *retval[], char *cmd){
    char *tmp;
    char a[100];
    strcpy(a,cmd);
    int i = 0;
    tmp = strtok(a," \n\t\0");

    if(retval == NULL){
        fprintf(stderr, "Error with allocation\n");
        return;
    }
    if(tmp == NULL){
        printf("Error with parsing.\n");
        return;
    }
    while(tmp != NULL){
        retval[i] = tmp;
        tmp = strtok(NULL," \n\t\0");
        i++;
    }
    retval[i] = NULL;
}

Вот вывод:

shell> ls 
ls
i i 
Error: exec no file or directory found 

1 Ответ

0 голосов
/ 05 марта 2019

Я почти уверен, что strtok возвращает указатель, который ссылается на тот первый аргумент, который, в вашем случае, является выделением стека.Я верю, что возвращение массива указателей на это выделение стека приведет к неопределенному поведению.Это может или не может быть причиной вашей проблемы.Это трудно понять, не видя больше кода.Чтобы протестировать, попробуйте изменить эту часть своего кода следующим образом:

void parse_cmd(char *retval[], char *cmd){
    char *tmp;
    char *a = strdup(cmd);
    int i = 0;

Перед использованием в работе вам нужно найти какой-то способ убедиться, что вы освободили "a", или вы получите утечку,Может быть, вы могли бы просто вернуть его вместо void и освободить его из другого места, или вы могли бы на самом деле strdup () каждый токен и написать функцию, чтобы освободить их всех или все, что работает для вас.

Если есть другие проблемы,они могут быть в другом коде.Я действительно не вижу здесь ничего плохого.

...