2012-01-28 6 views
1

私はpipe、fork、dup2を使って "ls | more "または" ls |ソート "など 私はここで問題を理解することができません。私は私のプログラムを実行すると 、私はこのエラーを取得する:パイプ、フォーク、dup2に関する問題がある

./a.out 
Missing filename ("less --help" for help) 

は、なぜ私が「少ない」取得しています?

このコードで何が問題になっていますか?私が "more"を "ls"に再度変更すると、うまく動作します。私は、lsをやっているのと同じです。 ls。

#define STDIN 0 
#define STDOUT 1 

int main() 
{ 
    int fd[2]; 
    int pid; 
    char *lschar[20]={"ls",NULL}; 
    char *morechar[20]={"more",NULL}; 
    pid = fork(); 
    if (pid == 0) { 
    /* child */ 
    int cpid; 
    cpid = fork(); 
    if(cpid == 0) { 
     //printf("\n in ls \n"); 
     pipe(fd); 
     dup2(fd[1], STDOUT); 
     close(fd[0]); 
     close (fd[1]); 
     execvp("ls",lschar); 
    } else if(cpid>0) { 
     waitpid(cpid, NULL,0); 
     dup2(fd[0],STDIN); 
     close(fd[0]); 
     close(fd[1]); 
     execvp("more", morechar); 
    } 
    } else if (pid > 0) { 
    /* Parent */ 
    waitpid(pid, NULL,0); 
    } 
    return 0; 
} 

あなたのご協力をお待ちしております。

+4

「なぜ「less」」と表示されるのですか? 'more'コマンドは、マシン上の' less'コマンドによって実装されるためです。 – smparkes

+0

よろしいですか?しかし、なぜそのエラー?何か案が ?私はこのプログラムの問題は見ていない。試したgdbも成功しなかった。 – Vin

+0

私はあなたが達成しようとしていることを100%確信しているわけではありませんが、引数なしで 'more' /' less'を呼び出しているのでエラーが発生しています。引数なしで 'ls'を実行できますが、' less'では実行できません。コマンドラインから試してみてください。それはあなたに同じエラーを与えるでしょう。 – smparkes

答えて

6

あなたの主な問題は、pipe()コールの配置にあります。あなたはfork()あなたがそれを呼び出す必要があります。

#include <unistd.h> 
#include <stdio.h> 
#include <sys/types.h> 

#define STDIN 0 
#define STDOUT 1 

int main() 
{ 
    int fd[2]; 
    int pid; 
    char *lschar[20]={"ls",NULL}; 
    char *morechar[20]={"more", NULL}; 
    pid = fork(); 
    if (pid == 0) { 
    /* child */ 
    int cpid; 
    pipe(fd); 
    cpid = fork(); 
    if(cpid == 0) { 
     //printf("\n in ls \n"); 
     dup2(fd[1], STDOUT); 
     close(fd[0]); 
     close (fd[1]); 
     execvp("ls",lschar); 
    } else if(cpid>0) { 
     dup2(fd[0],STDIN); 
     close(fd[0]); 
     close(fd[1]); 
     execvp("more", morechar); 
    } 
    } else if (pid > 0) { 
    /* Parent */ 
    waitpid(pid, NULL,0); 
    } 
    return 0; 
} 

そうでない場合は、より多くのプロセスが正しいファイル記述子を持っていません。さらに、あなたのより多くのプロセスのwaitpid()は問題があり不必要です(それ以上の入力を待つことになります)。 lsの出力が特に長い場合、パイプがいっぱいになり、lsが書き込みをブロックする可能性があります。結果はデッドロックであり、永遠に待ちます。したがって、私はまた、怒っているwaitpid()コールを削除しました。あなたが作る場合

はまた、pipe()dup2()のように、このエラーを関数の戻り値をチェックすることをお勧めは見つけることがはるかに簡単だっただろう - あなたはあなたのdup2()が失敗していたことを見ているだろう。

+1

さて、あなたが見たエラーメッセージは、 'stdin'がttyかどうかを確認する' 'isatty(0)'を呼び出す可能性が最も高いです。これは、引数なしで実行しているのか、実際に何かを引数に渡しているのかを区別する方法です。あなたのポケットに貼り付けるもう一つの便利なPOSIX呼び出し;) – FatalError

+0

ありがとうございました。今は働いている! :) – Vin

関連する問題