5

シェルを構築していますが、システムコール「execvp」で問題が発生しています。私はこのトピックに関する他のいくつかの質問を見ましたが、それらは曖昧であり、完全に対処されているようには見えませんでした(質問をした人は多くの情報を提供せず、良い答えを得ることができませんでした)。

明らかに、私は独自のコマンドラインを持っており、stdinからのユーザー入力を次のように読み取っています。

mysh some/path $ ps -a 

args配列をchar**として作成していますが、関数内の値を出力すると、配列自体が機能します(私は思います)。

args[0] = 'ps'
args[1] = '-a'
args[2] = '(null)'

したがって、プロセス内でforkとexecvp(cmnd、args)を呼び出します。ここで、cmndは「ps」であり、argsは上記のとおりであり、perrorなどです。

私は得る

'Error: no such file or directory.'  

$ PATH変数を入力する必要がありますか?私は何か他の奇抜なことをしていますか?

args配列を生成するための私のコードは次のとおりです。

char ** get_args(char * cmnd) {
int index = 0;
char **args = (char **)emalloc(sizeof(char *));
char * copy = (char *) emalloc(sizeof(char)*(strlen(cmnd)));
strncpy(copy,cmnd,strlen(cmnd));
char * tok = strtok(copy," ");
while(tok != NULL) {
    args[index] = (char *) emalloc(sizeof(char)*(strlen(tok)+1));
    strncpy(args[index],tok,strlen(tok)+1);
    index++;
    tok = strtok(NULL," ");
    args = (char**) erealloc(args,sizeof(char*)*(index+1));
}
args[index] = NULL;
return args;
}

(emallocとereallocは、エラーチェックが組み込まれたmallocとreallocです)

だから私はこれを行います:

void exec_cmnd(char*cmnd, char**args) {
pid_t pid;
if((pid=fork())==0) {
    execvp(cmnd, args);
    perror("Error");
    free(args);
    free(cmnd);
    exit(1);
}
else {
    int ReturnCode;
    while(pid!=wait(&ReturnCode)) {
        ;
    }
}
}

そして、上で述べたように、プロセス内でexecvpが呼び出されると、引数を指定しても失敗しますが、引数がないと機能します(つまり、argv == {'ps'、NULL}の場合)。

さらに詳しい情報が必要な場合は、遠慮なくお問い合わせください。これを解決する必要があります。

4

2 に答える 2

6

最初の引数でコマンドライン全体をに渡したと思いますexecvp

cmndの最初の引数として渡すには、から最初のトークン(コマンド名)を分離する必要がありますexecvp

あなたはそれを次のように呼ぶことができます

execvp(args[0], args);

于 2012-05-22T01:11:23.827 に答える
1

次の結果として、終了していない文字列があることに注意してください。

char * copy = (char *) emalloc(sizeof(char)*(strlen(cmnd)));
strncpy(copy, cmnd, strlen(cmnd));

strncpy()あなたがそのようにそれを使うときあなたのためにnull終了しません。また、nullにもう1バイトを割り当てる必要があります。strdup()利用可能な場合は、使用を検討してください。そうでない場合は、それを書くことを検討してください。この誤割り当ては、とのバージョンのエラーチェックでも問題にemalloc()なりerealloc()ます。

于 2012-05-22T01:46:13.850 に答える