1
[...] Preprocesser directives

void read_command()
{
    int i;                                //index to the arrays stored in parameter[]
    char *cp;                             //points to the command[]
    const char *hash = " ";               //figures out the strings seperated by spaces
    memset(command, 0, 100);              //Clear the memory for array
    parameter[0] = "/bn/";                //Initialize the path

    //Get the user input and check if an input did occur
    if(fgets(command, sizeof(command), stdin) == NULL)
    {
        printf("Exit!\n");
        exit(0);
    }

    //Split the command and look store each string in parameter[]
    cp = strtok(command, " ");            //Get the initial string (the command)
    strcat(parameter[0], cp);             //Append the command after the path
    for(i = 1; i < MAX_ARG; i++)
    {
        cp = strtok(NULL, " ");           //Check for each string in the array
        parameter[i] = cp;                //Store the result string in an indexed off array
        if(parameter[i]  == NULL)
        {
            break;
            cp = NULL;
        }
    }
    //Exit the shell when the input is "exit"
    if(strcmp(parameter[0], "exit") == 0)
    {
        printf("Exit!\n");
        exit(0);
    }

}


int main()
{

    [...]

        read_command();
        env = NULL;                                 //There is no environment variable

            proc = fork();
            if(proc == -1)                              //Check if forked properly
            {
                perror("Error");
                exit(1);
            }
            if (proc == 0)                             //Child process
            {
                execve(parameter[0], parameter, env);  //Execute the process
            }
            else                                       //Parent process
            {
                waitpid(-1, &status, 0);               //Wait for the child to be done
            }

    [...]
}

コードの基本的な考え方は、ユーザーによる入力コマンドを読み取ることですread_command()(関数で実行されます) (例: ls -l)。次に、入力文字列を小さな文字列に分割し、それらを配列に格納します。ポイントは、コマンドをパラメーター [0] (例: ls) に格納し、パラメーターをパラメーター [1,2,3 etc.] (例: -l) に格納することです。execve()ただし、関数を正しく実行していないと思います。

4

1 に答える 1

2

コードには、次のようなすべての種類の問題があります(Jonathan Lefflerによって正しく指摘されているものもあります)。

  1. "/bin/"スペルミス"/bn/"
  2. の文字列リテラル( )をparameter[0]指しているので、この文字列リテラルに追加しようとしていますが、これは正しくありません。代わりに、連結された文字列を保持するためのバッファを割り当てる必要があります。"/bn/"strcat(parameter[0], cp);
  3. commandトークン化コードは、末尾の改行を適切に処理しません。
  4. env文字列のNULLで終了する配列を指す必要があります。

一般に、より大きなプログラムに統合する前に、コードの一部を適切に実装してテストすることに集中する必要があると思います。read_command結果をに渡そうとする前にテストした場合execve、それが機能しないことに気付くでしょう。

于 2011-10-12T07:37:51.097 に答える