execvp() - неподдерживаемая опция SysV

Я пытаюсь написать простую оболочку на C, которая принимает команду и использует дочерний процесс для выполнения этой команды. Например, если я введу:

ps -ael  

мой дочерний процесс должен выполнить эту команду вместе с ее аргументами. Я распечатываю свои команды, поскольку они хранятся в массиве. Вот что я вижу:

Array[0] = ps
Array[1] = -ael  
Array[2] = NULL

Когда я выполняю, я получаю это:

error: unsupported SysV option

Usage:
 ps [options]

 Try 'ps --help <simple|list|output|threads|misc|all>'
  or 'ps --help <s|l|o|t|m|a>'
 for additional help text.

For more details see ps(1). 

Мой код ниже.

int main(void)
{
    char *args[MAX_LINE/2 +1]; // command line arguments
    char *cmdLine;
    int should_run = 1; // flag to determine when to exit the program
    int i, x;


    printf("osh> ");
    fflush(stdout);
    fgets(cmdLine, MAX_LINE, stdin);


    char *token = strtok(cmdLine, " ");
    int position = 0;
    while (token != NULL)
    {
        args[position++] = token;
        token = strtok(NULL, " ");
    }
    i = 0;
    while (args[i] != NULL)
    {
        printf("Array[%d] = %s\n", i, args[i]);
        i++;
    }
    if (args[i] == NULL) printf("Array[%d] = NULL", i);
    x = 0;
    pid_t pid;

    /* fork a child process*/
    pid = fork();

    if (pid < 0)
    {
        /*Error occured*/
        fprintf(stderr, "Fork failed.");
        return 1;
    }
    else if (pid == 0)
    {
        /*child process*/

        execvp(args[0], args); //error here
    }
    else
    {
        /*Parent process*/

        wait(NULL);

        printf("\nChild complete\n");
    }

}

1 ответ

Решение

Строка, возвращаемая fgets() включает символ новой строки, но вы не удаляете его из строки. Итак, вы устанавливаете args[1] в "-ael\n", а также \n не является допустимым вариантом.

Включить новую строку в свой strtok() разделители:

char *token = strtok(cmdLine, " \n");
int position = 0;
while (token != NULL)
{
    args[position++] = token;
    token = strtok(NULL, " \n");
}

и тогда он не будет включен в токены.

Вы должны были увидеть это в своем выводе, я готов поспорить, что он напечатан:

Array[0] = ps
Array[1] = -ael  

Array[2] = NULL

с пустой строкой там.

Кстати, я не вижу, где вы когда-либо устанавливали последний аргумент NULL, while цикл останавливается, когда strtok() возвращается NULLпоэтому он никогда не присваивает этот результат args[position++], Вам нужно добавить:

args[position] = NULL;

после петли.

И нет необходимости if (args[i] == NULL) - цикл до этого останавливается при выполнении этого условия, поэтому он гарантированно будет истинным.

Другие вопросы по тегам