|
アドバイスありがとうございます。
2日悩んで括弧が原因か…
なんとか目的のプログラムも出来てきたのですが、ここでまた問題が…
プログラムというのが、シェルの|,<,>を!,+,=に置き換えて実行できるというもので、例えばシェルで
ls | sort -r > kekka.txt
ならば、
./fake_sh ls ! sort -r = kekka.txt
(fake_shはプログラム名)とすると同様の結果が得られるというものです。
上と同じならば現時点でうまくいくのですが、
./fake_sh ls ! sort -r ! sort
のようにパイプが2つ以上になるとうまく出力されません。
どなたか原因のアドバイスをお願いします。
プログラムでパイプはpfd[10][2]と10個宣言されており、上記のように実行すると
ls →入力デフォルト,出力pfd[0][1]
sort -r →入力pfd[0][0],出力pfd[1][1]
sort →入力pfd[1][0],出力デフォルト
となっています(私の意図したとおりなら)。
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
int main(int argc,char *argv[]){
int i,j,cnt,val,pfd[10][2],check=0;
char *filename[2];
char *command[10];
int fd,fd2;
j = 0;
i = 1;
while(1){
for(cnt = 0;i < argc && *argv[i] != '!' && *argv[i] != '+' && *argv[i] != '='; i++,cnt++){
command[cnt] = argv[i];
}
if(cnt ==0){
break;
}
command[cnt] = NULL;
if(i <argc && *argv[i] == '+'){
i++;
filename[0] = argv[i];
i++;
check |=1;
}
if(i <argc){
switch(*argv[i]){
case '=':
i++;
filename[1] = argv[i++];
check |= 2;
break;
case '!':
i++;
pipe(pfd[j]);
check |=4;
break;
}
}
switch(fork()){
case 0:
if(check & 8){//1つ前の子プロセスからパイプで渡された時
dup2(pfd[j-1][0],0);
close(pfd[j-1][1]);
}
if(check & 1){//リダイレクトでファイルから入力
if((fd = open(filename[0],O_RDONLY)) ==-1){
printf("open error!\n");
exit(-1);
}
dup2(fd,0);
}
if(check & 2){//リダイレクトでファイルへ出力
if((fd2 = open(filename[1],O_WRONLY|O_CREAT,0600)) ==-1){
printf("open error!\n");
exit(-1);
}
dup2(fd2,1);
}
if(check & 4){//パイプへ出力
dup2(pfd[j][1],1);
close(pfd[j][0]);
}
execvp(command[0],command);
perror("child process1\n");
case -1:
perror("child process2\n");
break;
default:
if(check & 4){
check = 8;
j++;
}
else{
check = 0;
}
}
}
wait(&val);
}
ちなみにパイプやリダイレクトは、半角スペースで一つ一つ区切らないとうまくいかないです。
タイトル変えたときはスレッド新しく立てた方がいいじゃろか?
|