0

pipes()forks()exec()dup()を使用してシェルをシミュレートしています。途中でガイドするstackoverflowに関するいくつかの投稿を見てきました。しかし、私のプログラムには、他の人がここで遭遇したのと同様の問題があるようです。

LinkedList構造体を使用します:char*cmdおよびchar**args(例:cmd ='ls' args ='-l -d')

出力結果は次のとおりです。ls-lls-l -a(必要な数の引数)ls -l | 選別

ls -l | wc -w (runs but spits out wrong value)
ls | wc -w (runs, but spits out the wrong value)
ls (alone - no args, spits out A NULL argv[0] was passed through an exec system call.)
ls -l | sort | wc -w (causes system to hang)

少なくとも、複数の引数を取得しているように見せかけますが、無効な結果またはシステムがハングしています。

void runCommand(Node* head)
{
    int old_fd[2], new_fd[2];
    int isValid, cpid, pid;

    //Loop through all commands
    for(int cmd = 0; cmd < cmdCount; cmd++)
    {
        //if(curr cmd has next cmd)
        if(cmd+1 < cmdCount)
        {
            //Create pipe new_fd
            if( pipe(new_fd) == -1) //pipe error
            {
            perror("Pipe Error.");
            exit(-1);
            }
        }

        //Parent
        if( (pid=fork()) != 0 ) //parent
        {
            //Wait for child process
            //wait(0); //moved below

            //Curr cmd has next command
            if(cmd+1 < cmdCount)
            {
                old_fd[0] = new_fd[0];
                old_fd[1] = new_fd[1];
            }

            //Curr cmd has previous command
            if(cmd-1 > -1)
            {
            close(old_fd[0]);
            close(old_fd[1]);
            }
        }
        //Child process
        else //if fork() == 0
        {
            //Curr cmd has previous command
            if(cmd-1 > -1)
            {
                dup2(old_fd[0], 0); // setting up old_pipe to input into the child
                close(old_fd[0]);
                close(old_fd[1]);
            }

            //Curr cmd has next command
            if(cmd+1 < cmdCount)
            {
                close(new_fd[0]); // setting up new_pipe to get output from child
                dup2(new_fd[1], 1);
                close(new_fd[1]);
            }

            printf("Running command '%s': \n",getCmd(cmd,head));
            printf("Arguments: "); printArgs(cmd,head);
            //Below works for 1 cmd 1+ args, but not 1 cmd 0 arg or mult pipes
            isValid = execvp(getCmd(cmd,head), getArgs(cmd,head));

            if(isValid == -1)
            printf("%s: Command not found.\n", getCmd(cmd,head));
        }
     wait();

    }
}

このスレッドに注意してください:Another_Stack_Overflow_Exampleそこで例を使用し、関数を「動作中」のサンプルに置き換えました。彼らの作業サンプルは、「ls」のような引数のない単一のコマンドを除いて、ほとんどすべてで機能するようです。それは単に何もしません。入力を求めます

要求されたgetCmd()およびgetArgs()関数は次のとおりです。「getNode()」を呼び出すだけで、Node *構造体(char*とchar**および2つのintを含む)が返されます。getCmdはchar*cmdを抽出します。getArgsは抽出します。 char**引数。

char* getCmd(int index, Node* head)
{
  Node* curr = getNode(index,head);
  return curr->cmd;
}
char** getArgs(int index, Node* head)
{
  Node* curr = getNode(index,head);
  return curr->args;
}
4

1 に答える 1

0

2つのこと:

1. NULL で終了する配列をexecvp()に渡す必要があります。

execvp("ls", NULL); // invalid!!!

これは次のようになります。

const char *args[1] = { NULL };
execvp("ls", args);

2.「パイプオペレーター」| はシェル拡張であるため、 exec...関数では使用できません。そこで指定できる実行可能ファイルは 1 つだけです。

于 2012-10-21T20:29:45.887 に答える