проблеми със системното извикване на execvp

Създавам малка обвивка, за да разбера по-добре C. Използвам функцията getline на POSIX, за да получа низ и да го разделя на токени чрез интервала. Но когато се обаждам на execvp(), за да направя системното извикване, нищо не се случва.. Ако някой ми посочи къде е проблемът, който имам, очевидно пропускам нещо вероятно малко.. (Не съм включил целия код така че някои фигурни скоби ще липсват в долната част, просто игнорирайте това, съжалявам) Много благодаря

        char *args[3];  // array for the command and arguments

        cmd = strtok(line, " ");            
        args[0] = cmd;              // put the first command in the array

        for(int i = 1; i < whitespace+1; ++i){

            cmd = strtok('\0', " \n");
            args[i] = cmd;              // fill the array of strings with the arguments
        }
        args[2] = '\0';    // assign last element to NULL


        pid = fork();

        if(pid != 0){        
            waitpid(-1, &stat, 0); 
        }
        else{

            char *const *test[1];
            test[0] = '\0';
            execvp("/bin/ls", test[0]);
            execvp(args[0], &args[1]);

Точно в края е мястото, където имам проблеми, опитах и ​​двете версии на execvp поотделно, но нито една не работи и бях заседнал по този проблем от 2 дни.. Оценявам всякаква помощ, благодаря


person Daniel Callaghan    schedule 13.11.2014    source източник
comment
Вашият args[2] = '\0'; е неортодоксален (но законен) начин за задаване на нулев указател. Той също така ограничава вашата команда до най-много едно име на файл. Цикълът преди да стане малко излишен. След това имате две execvp() повиквания; ако първият успее, вторият няма да бъде изпълнен. Правилният начин за извикване на execvp() е execvp(args[0], args);. Трябва да имате код за съобщаване на грешка след execvp() -- ако се върне, значи е неуспешен -- и обикновено трябва да излезе.   -  person Jonathan Leffler    schedule 13.11.2014
comment
Имайте предвид, че getline() е разширение на GNU, което не е определено от POSIX. Имам само думите ви, че го използвате, тъй като не се появява в кода, който представихте.   -  person John Bollinger    schedule 13.11.2014
comment
Как е по-ортодоксален начин за задаване на нулев указател. Благодаря ви за съвета относно правилния начин за извикване на execvp.   -  person Daniel Callaghan    schedule 13.11.2014
comment
Имайте предвид, че когато execvp() работи, той не се връща, така че рядко е подходящо да го извиквате два пъти подред. Ако се върне, тогава е възникнала грешка и можете да разберете естеството на тази грешка чрез променливата errno, може би чрез функцията perror().   -  person John Bollinger    schedule 13.11.2014
comment
Какъв е по-ортодоксалният начин за задаване на нулев указател? args[2] = NULL; Ако NULL не е дефинирано, включете <stddef.h>   -  person Paul Roub    schedule 13.11.2014
comment
Съжалявам, че всъщност не извиквам execvp два пъти.. Коментирах този, използващ масиви, и тествах с литералния низ, за ​​да видя дали това е проблем с настройката на моя масив. Благодарим ви за предложението за заглавния файл NULL   -  person Daniel Callaghan    schedule 13.11.2014


Отговори (1)


Ето минимален пример за това как да накарате execvp да работи.

#include <stdio.h>
#include <unistd.h>

int main( void )
{
    char *test[2];              // declare an array of pointers
    test[0] = "/bin/ls";        // first arg is the path to the executable
    test[1] = NULL;             // NULL terminator indicates no additional args
    execvp( test[0], test );
}

Ето обяснение от man страницата за execvp

Първият аргумент, по конвенция, трябва да сочи към името на файла, свързан с файла, който се изпълнява. Масивът от указатели трябва да завършва с NULL указател.

person user3386109    schedule 13.11.2014