Проблемы с созданием простой оболочки Unix - PullRequest
0 голосов
/ 01 апреля 2010

Я пытаюсь создать простую оболочку в Unix. Я много читал и обнаружил, что все часто используют функцию strtok. Но я хочу сделать это без каких-либо специальных функций. Поэтому я написал код, но не могу заставить его работать. Что я тут не так делаю?

void process(char**);
int arg_count;
char **splitcommand(char* input)
{
    char temp[81][81] ,*cmdptr[40];
    int k,done=0,no=0,arg_count=0;
    for(int i=0 ; input[i] != '\0' ; i++)
    {
        k=0;
        while(1)
        {
            if(input[i] == ' ')
            {
                arg_count++;
                break;
            }
            if(input[i] == '\0')
            {
                arg_count++;
                done = 1;
                break;
            }
            temp[arg_count][k++] = input[i++];
        }
        temp[arg_count][k++] = '\0';
        if(done == 1)
        {
            break;
        }
    }
    for(int i=0 ; i<arg_count ; i++)
    {
        cmdptr[i] = temp[i];
        cout<<endl;
    }
    cout<<endl;
}


void process(char* cmd[])
{
    int pid = fork();
    if (pid < 0)
    {
        cout << "Fork Failed" << endl;
        exit(-1);
    }
    else if (pid == 0)
    {
        cout<<endl<<"in pid";
        execvp(cmd[0], cmd);
    }
    else
    {
        wait(NULL);
        cout << "Job's Done" << endl;
    }
}


int main()
{
    cout<<"Welcome to shell !!!!!!!!!!!"<<endl;
    char input[81];
    cin.getline(input,81);
    splitcommand(input);
}

Ответы [ 5 ]

2 голосов
/ 01 апреля 2010

Это почти наверняка домашнее задание. Нет причин избегать библиотечных функций, если вам не сказали об этом. На самом деле, скорее всего, вам сказали ввести strtok.

2 голосов
/ 01 апреля 2010

Несколько вещей:

  • вы ничего не возвращаете из функции splitcommand
  • все, что вы делаете в функции splitcommand, делается в локальных переменных, поэтому она (особенно строки, которые вы делаете) не переживет своего конца
  • неправильный код, который присоединяет нулевой терминатор (вы помещаете его в следующую строку, а не в текущую)
  • использование буфера фиксированного размера - отличный выбор; людям это нравится
  • обратите внимание, что в реальных оболочках UNIX не каждый пробел обозначает аргумент и не каждый аргумент обозначается пробелами

Я бы посоветовал вам использовать строки и некоторые (настоящие) средства синтаксического анализа, если они не слишком особенные для вас.

1 голос
/ 01 апреля 2010

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

Например:

http://en.wikipedia.org/wiki/Flex_lexical_analyser

1 голос
/ 01 апреля 2010

strtok на самом деле не особая функция, так как стандартная функция включает в себя string.h , поэтому нет веских причин не использовать ее.

0 голосов
/ 01 апреля 2010

Проблема с

arg_count++;  

внутри if(input[i] == ' ') и if(input[i] == '\0')

когда вы анализируете командную строку и находите пробел или достигаете конца командной строки, вы увеличиваете arg_count, прежде чем поставить \0 в конце команды, которую вы читали.

Так что измените его на:

        if(input[i] == ' ')  
        {  
            // arg_count++;  REMOVE THIS.
            break;  
        }  
        if(input[i] == '\0')  
        {  
            // arg_count++;  REMOVE THIS.
            done = 1;  
            break;  
        }  
        temp[arg_count][k++] = input[i++];  
    }  
    temp[arg_count][k++] = '\0'; // add null-char at the end. 
    arg_count++; // increment should happen here.

Больше ошибок:

  • Вы ничего не возвращаете с splitcommand
  • Вы не можете просто вернуть cmdptr потому что они указывают на местный символ массивы (temp), которые не будут сохраняться после того, как функция вернется. Так что вы должны убедиться, что массив temp сохраняется даже после функции вызов, выделяя его динамически или делая его глобальным.
  • Аргументы execvp хорошо выглядят мне. Другие, пожалуйста, посмотрите.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...