Команда сохранения истории на простой оболочке кодом C - PullRequest
0 голосов
/ 13 октября 2019

Я пишу простую оболочку в linux на языке C. Я сохраняю команду в истории, а когда набираю !!, программа выполнит последнюю команду, сохраненную в истории. Но это не работает, проблема в том, что:
когда я набираю команду: ls, argv - это ls, а history - это ls, но затем я набираю !!, и argv, и history - !!. Кто-нибудь, помогите мне исправить эту ошибку. Большое спасибо !!

void  main(void)
{
     char  line[1024];             
     char  *argv[64];            
     char  *history[64];

     while (1) {                   
          printf("Shell -> ");    
          gets(line);              
          printf("\n");
          parse(line, argv);
          if (strcmp(argv[0], "exit") == 0) 
               exit(0);
          checkDoubleExclmt(argv, history);
          execute(argv);


     }
}
void copyArr(char** des, char** source)
{
   int i = 0;
   for(i; i < sizeof(source)/4; i++)
   {
        des[i] = source[i];
   }
}
void checkDoubleExclmt(char** argv, char** history)
{
    if(strcmp(argv[0], "!!") == 0)
    {
        if(history[0] == NULL)
        {
           printf("\nNo Command in history\n");
        }
        else
        {
           copyArr(argv, history);
        }
    }
    else
    {   
        copyArr(history, argv);
    }

}
void execute(char **argv)
{
     pid_t  pid;
     int    status;

     if ((pid = fork()) < 0) {
          printf("*** ERROR: forking child process failed\n");
          exit(1);
     }
     else if (pid == 0) {                
          if (execvp(*argv, argv) < 0) {    
               printf("*** ERROR: exec failed\n");
               exit(1);
          }
     }
     else {                                
          while (wait(&status) != pid)     
               ;
     }
}
void parse(char *line, char **argv)
{
     while (*line != '\0') {     
          while (*line == ' ' || *line == '\t' || *line == '\n')
               *line++ = '\0';     
          *argv++ = line;         
          while (*line != '\0' && *line != ' ' && 
                 *line != '\t' && *line != '\n') 
               line++;            
     }
     *argv = '\0';                 
}

1 Ответ

0 голосов
/ 13 октября 2019

Основная проблема, которую я вижу, заключается в том, что вы делаете копию указателя вместо его содержимого.

    des[i] = source[i]; // pointer copy

должно быть

   des[i] = strdup(source[i]); //creates memory and copies the contents. You need to free the memory before overwriting.

Если вы используете strdup ваш parse() функция должна быть изменена для размещения копии содержимого.


И

   for(i; i < sizeof(source)/4; i++)

sizeof(source это размер указателя, а не размер массива, вам нужно явно передать размерфункционировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...