Почему эти два execvp дают разные результаты? - PullRequest
1 голос
/ 10 мая 2019

Мне интересно, почему приведенные ниже результаты дают разные результаты:

char *const temp[] = {"cal","4","2019",NULL};


    execvp(temp[0],temp);
    perror("Return from execlp not expected");
    exit(EXIT_FAILURE);

при выполнении создаст календарь с ТОЛЬКО месяцем апреля

char *const temp[] = {"cal"};
char *const temp2[] ={"4","2019",NULL};

    execvp(temp[0],temp2);
    perror("Return from execlp not expected");
    exit(EXIT_FAILURE);

при выполнении создаст календарь со ВСЕМИ месяцами

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

array1[0] = command
array2[0] = arg1 ar2 arg3  // the arguments for the command in array1[0]

И в цикле, пока я не достигну конца моего массива команд, используйте fork и выполните эти команды в дочернем классе, чтобы я мог выполнить и выполнить все команды в массиве.

Ответы [ 2 ]

2 голосов
/ 10 мая 2019

Согласно execvp man

int execvp(const char *file, char *const argv[]);

Функции execv (), execvp () и execvpe () предоставляют массив указателей на строки с нулевым символом в конце, которыепредставляет список аргументов, доступных для новой программы. Первый аргумент, по соглашению, должен указывать на имя файла, связанное с исполняемым файлом. Массив указателей должен заканчиваться указателем NULL

0 голосов
/ 10 мая 2019

argv[0] всегда считается именем программы, даже если оно не используется execvp, как в вашем случае. Сама программа cal начинает интерпретировать командную строку с argv[1]. (См. @Kiran Biradar answer.)

Вам нужно будет скопировать (указатели на) аргументы в больший массив и установить фиктивный аргумент для argv[0]. Вот небольшой код для этого:

char **combine_args(char *arg0, char **tail) {
    size_t n = 0;
    while(tail[n]) ++n;
    char **ret = malloc(sizeof(char*)*(n+2));
    ret[0] = arg0;
    memcpy(ret + 1, tail, sizeof(char*)*n);
    ret[n+1] = 0;
    return ret;
}

Далее вы можете использовать его так:

char *const temp[] = {"cal"};
char *const temp2[] ={"4","2019",NULL};

char **argv = combine_args(temp[0], temp2);

execvp(argv[0], argv);
perror("Return from execlp not expected");
exit(EXIT_FAILURE);

Если вы делаете это в цикле и можете изменить массив temp2, то вы можете сделать это следующим образом, без каких-либо выделений:

char *const temp[] = {"cal", "cal2", "cal3", NULL};
char *temp2[] ={NULL, "4","2019",NULL};

for(int i = 0; temp[i]; ++i)
{
    // ... fork here ...
    {
        temp2[0] = temp[i];
        execvp(temp2[0], temp2);
        perror("Return from execlp not expected");
        exit(EXIT_FAILURE);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...