2016-04-07 12 views
0

こんにちは私はCでシェルをプログラミングしていましたが、リダイレクトしようとしている間に固執しました。私のプログラムでstdoutをリダイレクトしても、stdinは動作しません。シェルで入力と出力をリダイレクトする

void redirect(node_t* node){ 
    // mode 0: >$%d mode 1: < mode 2: > mode 3: >> 
    int input = 0; 
    if(node->redirect.mode == 2){ 
     input = 1; // > 
    } else{ 
     input = 0; // < 
    } 
    int pid = 0; 
    int *status = 0; 
    char * filename = node->redirect.target; // filename 
    int fd; 
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC); 
    if((pid = fork()) == 0){ 
     dup2(fd, input); // STDIN OR STDOUT 
     close(fd); 
     node_t* node2 = node->redirect.child; 
     execvp(node2->command.program, node2->command.argv); // execute program 
     printf("failed to execvp\n"); 
     exit(1);   
    } else { 
     wait(status); 
    } 
} 

は私がfork()に新たなんだけど、私の質問は、私がここで間違って標準出力の作品をリダイレクトするが、それを標準入力すると、指定したファイルに何も書き込まれないことをやっているものです。

+1

ファイル記述子が 'O_WRONLY | O_CREAT | O_TRUNC'の場合、子プロセスはそれからデータを読み取ることができません。 stdinリダイレクションの場合には 'O_RDONLY'を開く必要があります。 – Ctx

+0

@Ctx 'O_WRONLY'を' O_RDONLY'に置き換えましたが、何の効果もありませんでした。しかし、なぜ私はそれにstdinを書く必要があるので、データを準備する必要がありますか? –

+1

プロセスの標準入力をリダイレクトすることは、通常、そこから_read_へのファイル記述子を与えることを意味します(これは単に規約であり、技術的にはもちろんstdinに書き込むことも可能です)。 – Ctx

答えて

1

コメントに記載されているように、入力リダイレクションと出力リダイレクトのどちらを開くかによって、別のオープンオプションを使用する必要があります。これをifに入れることができます。

int flags; 
if(node->redirect.mode == 2){ 
    input = 1; // > 
    flags = O_WRONLY | O_CREAT | O_TRUNC; 
} else{ 
    input = 0; // < 
    flags = O_RDONLY; 
} 
int pid = 0; 
int *status = 0; 
char * filename = node->redirect.target; // filename 
int fd; 
fd = open(filename, flags, 0666); 

また、出力ファイルが作成されるケースの許可モードを指定する必要があります。常にこの引数を指定しても問題ありません。O_CREATがフラグにない場合は無視されます。

+0

あなたの答えに感謝しました。この疑問は、「ファイル記述子を正しく開く方法」であることが判明しました。 –