1 /* tingbc.c 2 * use two pipe to execute the bc. 3 * one pipe: todc[2] , another: fromdc[2] 4 * child thread to do dc, parent do UI 5 */ 6 7 #include <stdio.h> 8 #include <unistd.h> 9 #include <string.h> 10 #define oops(x, n) {perror(x); exit(n);} 11 12 void be_dc(int todc[], int fromdc[]); 13 void be_bc(int todc[], int fromdc[]); 14 int main(void) { 15 int todc[2], fromdc[2], pid; 16 if(pipe(todc)==-1 || pipe(fromdc)==-1) 17 oops("pipe", 2); 18 if((pid=fork()) == -1) 19 oops("fork" ,3); 20 if(pid==0) { 21 be_dc(todc, fromdc);//child do dc 22 }else{ 23 be_bc(todc, fromdc);//parent do UI 24 wait(NULL); 25 } 26 return 0; 27 } 28 29 void be_dc(int todc[], int fromdc[]){ 30 //will do dc() , change the stdin to todc[1], change the stdout to fromdc[0] 31 close(todc[1]); 32 close(fromdc[0]); 33 if(dup2(todc[0], 0)==-1) 34 oops("could not redirect the stdin", 4); 35 if(dup2(fromdc[1], 1)==-1) 36 oops("could not redirct the stdout", 5); 37 close(todc[0]); 38 close(fromdc[1]); 39 execlp("dc", "dc", "-",NULL); 40 oops("exe",1); 41 } 42 43 void be_bc(int todc[], int fromdc[]){ 44 //will do bc(), change the stdout to todc[1], and use the fromdc[0] to read the dc's result 45 char cmdbuf[BUFSIZ]; 46 int c1, c2; 47 char operator; 48 FILE *fout, *fread; 49 close(todc[0]); //donot need to todc out 50 close(fromdc[1]); //donot need to fromdc in 51 52 fout=fdopen(todc[1],"w"); //write the todc[1] 53 fread=fdopen(fromdc[0],"r" ); //read the dc's result from fromdc[0] 54 55 while((printf("tinybc: ")) && (fgets(cmdbuf, BUFSIZ, stdin )!=-1)) { 56 if( sscanf(cmdbuf, "%d %c %d", &c1,&operator,&c2) !=3) { 57 printf("syntax error. "); 58 continue; 59 } 60 printf("2u cin is %d %c %d ", c1,operator,c2); 61 if(fprintf(fout, "%d %d %c p ", c1,c2,operator) == EOF)//在这里有问题,c1总是读不进去,一直是0. 62 oops("fprintf", 6); 63 64 fflush(fout); 65 if(fgets(cmdbuf, BUFSIZ, fread)==NULL) 66 break; 67 printf("%d %c %d = %s", c1, operator, c2, cmdbuf); 68 } 69 close(todc[0]); 70 close(fromdc[1]); 71 }
这里,在2个pipe使用时,要分清楚pipe[0],pipe[1]哪一个是读出哪一个是写入。
同时这里用到了sscanf函数。
/**********************************************************************************************/
sscanf(格式化字符串输入)
相关函数 scanf,fscanf
表头文件 #include<stdio.h>
定义函数 int sscanf (const char *str,const char * format,........);
函数说明 sscanf()会将参数 str 的字符串根据参数 format 字符串来转换并格
式化数据。格式转换形式请参考 scanf()
。转换后的结果存于对应
的参数内。
返回值
成功则返回参数数目,失败则返回-1,错误原因存于 errno 中。
范例
#include<stdio.h>
main()
{
int i;
unsigned int j;
char input[ ]=”10 0x1b aaaaaaaa bbbbbbbb”;
char s[5];
sscanf(input,”%d %x %5[a-z] %*s %f”,&i,&j,s,s);
printf(“%d %d %s
”,i,j,s);
}
/***************************************************************************************/
fdopen函数
fdopen函数与fopen类是,返回一个FILE*类型值,不同的是此函数以文件描述符而非文件作为参数。
使用fopen的时候,将文件名作为参数传给它。fopen可以打开设备文件也可以打开常规的磁盘文件。如只知道文件描述符而不清楚文件名的时候可以使用fdopen。
使用fdopen使得对远端的进程的处理就如同处理常规文件一样