1

C で基本的なシェルを実装する必要があります。必要なことの 1 つは、コマンドを持つ関数を実装して実行することです。私のコード:

    pID=fork();

    if (pID == 0)
       execvp(tmp[0], tmp);
    else if (pID > 0)
    {
       printf("%d", pID);
       wait(NULL);
    }
    else
      printf("Failed to create proccess \n");

問題は、tmp に入力したコマンドが何であっても、プログラムが再度プロンプトを表示し、それ以外は何もしないことです。たとえば、 ( Ubuntuのntpadgeditを開くために)書いた場合、それは開かれません。または、書いた場合、Ubuntuの端末のように出力が表示されません。geditls -a

4

3 に答える 3

2

execvp が動作するはずです。他の人が述べたように、tmp にデータを入力する方法を示す必要があります。そうは言っても、それがエラーの場所だと思います。tmp はヌルで終了する配列である必要があります。

#include <stdio.h>
main( int argc, char * argv[] )
{
int    pid = fork;
char * tmp[2];
  memset( tmp, 0, sizeof(tmp) );
  tmp[0] = argv[0];
  if( 0 == pid )
  {
    if( -1 == execvp( tmp[0], tmp ) )
    {
      char errmsg[64];
      snprintf( errmsg, sizeof(errmsg), "exec '%s' failed", tmp[0] );
      perror( errmsg );
    }
  else if( 0 < pid )
  {
    printf("[%d] %s\n", pid, tmp[0]);
    wait(NULL);
  }
  else
  {
    perror("fork failed");
  }
}
于 2012-08-22T22:21:42.117 に答える
1

tmp変数を介して に何を渡しているかを教えてくれませんでしたがexecvp、私の精神的な感覚は、引数リストを null で終了するのを忘れていたことを示しています。NULL 引数はexecvp、最後の引数がどこにあるかを示します。NULL の入力に失敗すると、スタックからランダムなガベージの読み取りが開始されます。

そのランダムなガベージがゼロ以外のデータの大きな文字列を指している場合、想定される引数を新しいプロセスに格納するためのスペースが不足します。これは通常、数百 KB です (システム固有の数値については、このページも参照してください)。システムの最大引数サイズを取得するさまざまな方法として)。

引数データが​​多すぎると、システム コールexecve(2)( によって内部的に呼び出されるexecvp) がエラー で失敗しますE2BIG

これがあなたに起こっていることかどうかを確認するには、 からの戻り値を確認してくださいexecvp。まったく返されない場合でも、失敗しました (成功した場合、新しいプロセスが実行されているため、返されていません!) のグローバル値をチェックして、errno失敗した理由を確認します。

if (pID == 0)
{
    execvp(tmp[0], tmp);
    printf("exec failed: %s\n", strerror(errno));
    exit(1);
}
于 2012-08-22T22:35:39.207 に答える