Ошибка ERFOR "внутренняя ошибка фатального сканера - конец буфера" пропущена при обработке CTRL + C - PullRequest
0 голосов
/ 28 апреля 2019

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

static sigjmp_buf env;              

void sigint_handler(int signo){     
    siglongjmp(env, 42);            
}                                   


void myShellLoop(){                                                                  
    int parserStatus;                                                                

    signal(SIGINT, sigint_handler);                                                  

    while(1){                                                                        
        if(sigsetjmp(env,1)==42){                                                    
            printf("\n");                                                            
            continue;                                                                
        }                                                                            
        //Initialize a new command, to parse and execute.                            
        initializeGlobalCommand();                                                   

        parserStatus = yyparse();                                                    
        if(parserStatus == 0)                                                        
            executeShellCommand();                                                   
        else                                                                         
            printf("Not a valid shell command\n");                                   
    }                                                                                
}                                                                                    

Но после того, как я нажимаю Ctrl + C, он переходит на новую строку, но затем flex дает мне эту ошибку:

fatal flex scanner internal error--end of buffer missed

Вот скриншот: enter image description here

Как правильно обрабатывать ctrl + c?

Редактировать: Фрагмент кода для fork ():

int execute(int cmdNumber){                                                                                                 
    pid_t pid;                                                                                                              
    int status;                                                                                                             

    pid = fork();                                                                                                           

    if(pid == 0){                                                                                                           
        signal(SIGINT, SIG_DFL);                                                                                            
        if(execvp(globalCommand.sCommands[cmdNumber].arguments[0], globalCommand.sCommands[cmdNumber].arguments) == -1){    
            perror("myShell: Command error");                                                                               
            exit(EXIT_FAILURE);                                                                                             
        }                                                                                                                   
    }                                                                                                                       
    else if(pid < 0){                                                                                                       
        //Error forking.                                                                                                    
        perror("myShell");                                                                                                  
    }                                                                                                                       
    else{                                                                                                                   
            do{                                                                                                                                                                                                                  
                waitpid(pid, &status, WUNTRACED);                                                                                                                                                                             
            }while(!WIFEXITED(status) && !WIFSIGNALED(status) && !globalCommand.background);
    }
    return 1;
}


1 Ответ

0 голосов
/ 28 апреля 2019

Вы 'брутально' выходите из кода (f) lex (/ yacc / bison), чтобы вернуться в myShellLoop , поэтому неудивительно, что вносится несоответствие

Переопределить YY_INPUT, а при нажатии control-c вернуть специальный символ, чтобы вернуть специальное значение / токен, управляемый в вашем синтаксическом анализаторе, для вызова yyerror для прерывания обычным способом.

Например, в вашем файле лексера:

%{
...
extern void my_yy_input(char*, int *, int);

#undef YY_INPUT
#define YY_INPUT(b,r,s) my_yy_input(b,&r,s)

%}
...

с

static sigjmp_buf env;              

void sigint_handler(int signo){     
  siglongjmp(env, '@');            
}                                   

void my_yy_input( char * buff, int * nRead, int maxToRead )
{
  *nRead =  1;

  if(sigsetjmp(env,1 ) == '@') {                                                    
    *buff = '@';
    return;
  }

  *buff = getchar();
 }
...