#include <stdio.h>
#include <stdlib.h>
#define oops(m,x) {perror(m); exit(x);}
main()
{
int pid,todc[2],fromdc[2];
//make two pipes
if(pipe(todc)==-1||pipe(fromdc)==-1)
oops("get pipe failed.",1);
//get a process for user interface
if((pid=fork())==-1)
oops("fork failed ",2);
if(pid==0) //child is dc
be_dc(todc,fromdc);
else{ //parent is ui
be_bc(todc,fromdc);
wait(NULL); //wait for child
}
}
void be_dc(int in[2],int out[2])
{
close(in[1]);
close(out[0]);
if(dup2(in[0],0)==-1) //copy read end to 0
oops("dc:cannot redirect stdin ",3);
close(in[0]); //moved to fd 0
if(dup2(out[1],1)==-1) //dupe write end to 1
oops("dc:cannot redirect stdout",4);
close(out[1]); //moved to 1
execlp("dc","dc","-",NULL);
oops("cannot run dc",5);
}
void be_bc(int todc[2],int fromdc[2])
//从stdin读,然后转换成RPN,传送给pipe,然后
//从其他管道读入,并打印出
{
int num1,num2;
char operation[BUFSIZ],*fgets();
char message[BUFSIZ];
FILE *fpout ,*fpin;
int n_read;
close(todc[0]);
close(fromdc[1]);
fpout=fdopen(todc[1],"w");
fpin=fdopen(fromdc[0],"r");
if(fpout==NULL||fpin==NULL)
fatal("Error convering pipes to streams");
//main loop
while(printf("tinybc:"),fgets(message,BUFSIZ,stdin)!=NULL)
{
if(sscanf(message,"%d%[+-*/^]%d",&num1,operation,&num2)!=3)
{printf("syntax error/n");
continue;
}
if(fprintf(fpout,"%d/n%d/n%c/np/n",num1,num2,*operation)==EOF)
fatal("Error writing");
fflush(fpout);
if(fgets(message,BUFSIZ,fpin)==NULL)
break;
printf("%d%c%d=%s",num1,*operation,num2,message);
/*
这里刚开始有个小问题(当我的运算结果非常大的时候,不能一次输出,而留在管道里,下次再执行运算的时候输出的就是错误的结果),现在解决了,但不知道为什么。这个程序把数乘结果转换成字符串输出,每行最多能输出71个字节,为什么是71那?
ps:我的BUFSIZ是8192
*/
if(strlen(message)==71){
while(fgets(message,BUFSIZ,fpin)!=NULL)
{
printf("%s",message);
if(strlen(message)!=71)
break;
}
}
}
fclose(fpout);
fclose(fpin);
}
fatal(char *mess[])
{
fprintf(stderr,"Error :%s/n",mess);
exit(1);
}
#include <stdlib.h>
#define oops(m,x) {perror(m); exit(x);}
main()
{
int pid,todc[2],fromdc[2];
//make two pipes
if(pipe(todc)==-1||pipe(fromdc)==-1)
oops("get pipe failed.",1);
//get a process for user interface
if((pid=fork())==-1)
oops("fork failed ",2);
if(pid==0) //child is dc
be_dc(todc,fromdc);
else{ //parent is ui
be_bc(todc,fromdc);
wait(NULL); //wait for child
}
}
void be_dc(int in[2],int out[2])
{
close(in[1]);
close(out[0]);
if(dup2(in[0],0)==-1) //copy read end to 0
oops("dc:cannot redirect stdin ",3);
close(in[0]); //moved to fd 0
if(dup2(out[1],1)==-1) //dupe write end to 1
oops("dc:cannot redirect stdout",4);
close(out[1]); //moved to 1
execlp("dc","dc","-",NULL);
oops("cannot run dc",5);
}
void be_bc(int todc[2],int fromdc[2])
//从stdin读,然后转换成RPN,传送给pipe,然后
//从其他管道读入,并打印出
{
int num1,num2;
char operation[BUFSIZ],*fgets();
char message[BUFSIZ];
FILE *fpout ,*fpin;
int n_read;
close(todc[0]);
close(fromdc[1]);
fpout=fdopen(todc[1],"w");
fpin=fdopen(fromdc[0],"r");
if(fpout==NULL||fpin==NULL)
fatal("Error convering pipes to streams");
//main loop
while(printf("tinybc:"),fgets(message,BUFSIZ,stdin)!=NULL)
{
if(sscanf(message,"%d%[+-*/^]%d",&num1,operation,&num2)!=3)
{printf("syntax error/n");
continue;
}
if(fprintf(fpout,"%d/n%d/n%c/np/n",num1,num2,*operation)==EOF)
fatal("Error writing");
fflush(fpout);
if(fgets(message,BUFSIZ,fpin)==NULL)
break;
printf("%d%c%d=%s",num1,*operation,num2,message);
/*
这里刚开始有个小问题(当我的运算结果非常大的时候,不能一次输出,而留在管道里,下次再执行运算的时候输出的就是错误的结果),现在解决了,但不知道为什么。这个程序把数乘结果转换成字符串输出,每行最多能输出71个字节,为什么是71那?
ps:我的BUFSIZ是8192
*/
if(strlen(message)==71){
while(fgets(message,BUFSIZ,fpin)!=NULL)
{
printf("%s",message);
if(strlen(message)!=71)
break;
}
}
}
fclose(fpout);
fclose(fpin);
}
fatal(char *mess[])
{
fprintf(stderr,"Error :%s/n",mess);
exit(1);
}