Оболочка бесконечно зацикливается при вводе EOF C - PullRequest
0 голосов
/ 30 сентября 2018

Я новый программист на Си, который пытается создать свою собственную оболочку.Сама оболочка работает хорошо и правильно обрабатывает мои команды, но когда пользователь вводит символ EOF в качестве ввода в командную строку, моя оболочка просто бесконечные циклы.Мой код опубликован ниже, а также то, что я уже пытался (я также новичок в использовании GDB и Valgrind, но ни один из них, похоже, не поможет мне найти проблему).

Что я уже пробовал:

  1. Текущая реализация ниже пытается захватить возвращаемое значение getline и обработать случай, когда он возвращает -1 (когдаEOF читается).Однако это просто заставляет оболочку бесконечно зацикливать приглашение
  2. Я полностью заменил свой вызов функции на:

    if (fgets(command_line, MAX_CANON, stdin) == NULL) {
      printf("\nTo quit, please use the exit command: exit.\n");
    }
    

Насколько мне известно, приведенная выше замена должнаобрабатывать ввод символов EOF пользователем.Однако эта реализация с использованием fgets также вызывает бесконечный цикл командной строки.

Ниже моя текущая реализация, которая упоминается в # 1 выше:

Функция, вызываемая в main для чтения ввода от пользователя:

char *read_command_line(void)
{
    //Declare an integer to hold the length of the string, a line to hold our output, and a variable getline can use to hold the generated buffer
    int len;
    char *line = NULL;
    ssize_t bufsize = 0;

    //Get the line from stdin 
    int retval = getline(&line, &bufsize, stdin);

    if(retval == -1)
    {
        line = NULL;
        return line;
    }

    //Determine the length of the line and set a null terminating byte to end the string and get rid of the trailing return
    len = strlen(line); 
    line[len - 1] = '\0';

    //Finally return the read in line
    return line;
}

Начало моей оболочки во время цикла, в котором читается строка:

//BEGIN SHELL
  while (go)
  {
    //Signals are handled in the main.c  
    //Print the prompt
    char cwd_loop[max_buf_size];
    getcwd(cwd_loop, sizeof(cwd_loop));
    printf("\n%s [%s]:> ", prompt_prefix, cwd_loop);

    commandline = read_command_line();  

    if(commandline == NULL)
    {
        continue;
    }

Ответы [ 2 ]

0 голосов
/ 30 сентября 2018

Из вашего кода

commandline = read_command_line();  

if(commandline == NULL)
{
    continue;
}

Если read_command_line возвращает нулевой указатель, что происходит при возникновении ошибки типа EOF, тогда вы продолжаете цикл, позволяя емуповторить еще раз.На этот раз read_command_line снова вернет , вернет нулевой указатель, и вы продолжите так вечно.

Вы должны break выйти из цикла, если read_command_lineвозвращает нулевой указатель.

0 голосов
/ 30 сентября 2018

Вы не должны продолжать запрашивать и читать дальнейшие вводные данные, когда входной поток закрыт, как указано getline(), возвращающим -1 или fgets(), возвращающим NULL.Просто вырвитесь из цикла, как если бы была введена команда exit.

...