1

私は C で単純なシェルを書いています。実際には、i/o リダイレクトなどとうまくいっています。追加したいことの 1 つは、exec* 関数のバージョンを切り替える方法です。現在、私は execlp()、execvp()、および execve() に固執しています。

argv という配列に渡したいすべての引数があります。これはヌル終了文字列のヌル終了配列であるため、execv* では問題なく動作しますが、execlp() で動作させる方法が思い浮かびません。

これは私が今持っているものです:

if     (strcmp(exec_opt, "vp") == 0)
  error = execvp(argv[0], argv);          /* Execute vp */
else if(strcmp(exec_opt, "lp") == 0)
  error = execlp(argv[0], "", argv);      /* Execute lp */
else if(strcmp(exec_opt, "ve") == 0)
  error = execve(argv[0], argv, environ); /* Execute ve */
else
{
  // throw errors about exec_opt
}

if(error != 0)
{
  // do something about it
}

この構成では、コンパイラは構文をバフしませんが、機能しません。私も試してみました

 error = execlp(argv[0], (char*) argv);  /* As a single string */
 char* argv1 = argv[1];                  /* don't pass command itself */
 error = execlp(argv[0], argv1);         

さまざまな奇妙なことを行いますが、最終的には正しくありません。配列を可変引数リストに変換する方法はありますか? それを直接渡すと (可変引数リストは であるため、これが最も型的に意味がありますchar* argv[])、互換性のないポインターのキャストに関するコンパイラ エラーが発生します。

4

2 に答える 2

1

execlp()配列では実際には使用できません。を使用するexeclp()には、次のように記述する必要があります。

execlp(array[0], array[0], (char *)0);
execlp(array[0], array[0], array[1], (char *)0);
execlp(array[0], array[0], array[1], array[2], (char *)0);
execlp(array[0], array[0], array[1], array[2], array[3], (char *)0);
...

代替数の引数ごとに。execvp()これが、がレパートリーに追加された理由です( 1978 年には 7th Edition UNIX™には含まれていませんでしたが、1997 年にはSUS v2に含まれていました)。これは、 AFAIKexecvpe()では存在しません (また、提供されていない理由もわかりません)。


7版 UNIX にはexcevp()

デイブは次のように述べています。

第 7 版のマニュアルにはexecvp.

そして...部分的にはそうです。マニュアルには実際に含まれているため、報告する正誤表があると思います。

名前

execl、execv、execle、execve、execlp、execvp、exec、exece、environ – ファイルを実行する

あらすじ

execl(name, arg0, arg1, ..., argn, 0)
char *name, *arg0, *arg1, ..., *argn;
execv(name, argv)
char *name, *argv[ ];
execle(name, arg0, arg1, ..., argn, 0, envp)
char *name, *arg0, *arg1, ..., *argn, *envp[ ];
execve(name, argv, envp);
char *name, *argv[ ], *envp[ ];
extern char **environ;

説明

そのためexecvp()、NAMEセクションにリストされていますが、概要はありませんexecvp()(これは、欠落しているという結論に達するために調べたものです)。execvp()次のページに参​​照があります。

Execlpおよびexecvpは、 execlおよびexecvと同じ引数で呼び出されますが、ディレクトリのリストで実行可能ファイルを検索する際のシェルのアクションを複製します。ディレクトリリストは環境から取得されます。

execvp()というわけで、シノプシスをざっと読んで、シノプシスから抜けてしまったので失礼します。しかし、実際には、システム コールは第 7 版 Unix に存在していました。抜けを直してマニュアルを再発行する人はいないと思います。

私の印刷版 (はい、私当時のマニュアルの第 1 巻 (ISBN 0-03-061742-1) と第 2 巻 (ISBN 0-03-061743-X) の適切に製本されたバージョンの両方を印刷しました。入手しました。それらは 1989 年頃のものです) は、SYNOPSIS セクションに同じ省略があります。

于 2012-04-10T01:33:45.553 に答える
0

avcallを使用してみてください。私はそれを自分で使用したことはありませんが、ここで興味深い言及を見つけました: Passing parameters dynamic to variadic functions

于 2012-04-10T01:38:29.953 に答える