|
|
程序目的:
实现一个shell程序,可以实现:
1.重定向;
2.管道;
问题:在实现功能2(由函数ispipe实现)的时候,
a:如果使用"尝试1"中的代码,则可以实现ls -al /usr/include | more之类的功能,
但是程序运行完此命令后会退出!并非我本意!
b:如果使用"尝试2"中的代码,在键入ls -al /usr/include | more之后,感觉子进程2(pid1 == 0)
对于键盘输入响应有些问题,实在不好描述,请运行实验一下;但是如果在调用fork的进程中
加入sleep(5)之后就没有问题了,但这又不是我的本意(因为这需要在5秒之内"more"完)!
恳请高手解惑!不胜感激!
另外,如何贴代码讷呢?找了半天没找到....校园网,太慢了
代码如下:
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <sys/types.h>
- char buf[128],cmd1[10],cmd2[10],file[20];
- char *var1[20],*var2[20];
- int flag,flagcmd1,flagcmd2;
- int getcmd()/*get the command and the varialble*/
- {
- int i,j;
- i = j = 0;
- char *p = NULL;
- var1[0] = var2[0] = NULL;
- cmd1[0] = cmd2[0] = 0;
- printf(">");
- gets(buf);
- i = j = 0;
- flag = flagcmd1 = flagcmd2 = 0;
-
- p = strtok(buf," ");
- while(p != NULL){
- if(strcmp(p,"|") == 0){
- flag = 1;
- p = strtok(NULL," ");
- continue;
- }
- if(strcmp(p,"<") == 0){
- flag = 2;
- p = strtok(NULL," ");
- continue;
- }
- if(strcmp(p,">") == 0){
- flag = 3;
- p = strtok(NULL," ");
- continue;
- }
-
- if(flag == 0){
- if(flagcmd1 == 0){
- strcpy(cmd1,p);
- flagcmd1 = 1;
- } else {
- var1[i++] = p;
- p = strtok(NULL," ");
- }
- }else if (flag == 1){
- if(flagcmd2 == 0){
- strcpy(cmd2,p);
- flagcmd2 = 1;
- } else {
- var2[j++] = p;
- p = strtok(NULL," ");
- }
- }else if(flag == 2){
- strcpy(file,p);
- p = strtok(NULL," ");
- }else if(flag == 3){
- strcpy(file,p);
- p = strtok(NULL," ");
- }
-
- }
- var1[i] = NULL;
- var2[j] = NULL;
- printf("The command 1 is %s\n",cmd1);
- printf("The command 2 is %s\n",cmd2);
- return flag;
- }
- void onecmd()
- {
- pid_t pid;
- if((pid = fork()) < 0){
- printf("fork error\n");
- exit(0);
- } else if(pid == 0){ /*child*/
- execvp(cmd1,var1);
- printf("wrong command.\n");
- }else if(pid > 0) /*parent*/
- wait(NULL);
-
- }
- void onecmdin(int fd[2])
- {
- pid_t pid;
- int n,m;
- char ch;
- int fp;
- if((fp =open(file,O_RDONLY)) == -1){
- printf("can't open %s\n",file);
- exit(0);
- }
- if(pipe(fd) < 0){
- printf("pipe error\n");
- exit(0);
- }
- if((pid = fork()) < 0){
- printf("fork error\n");
- exit(0);
- } else if(pid > 0){ /*parent*/
- close(fd[0]);
- while(read(fp,&ch,1) != 0 )
- write(fd[1],&ch,1);
- close(fd[1]);
- if(waitpid(pid,NULL,0) < 0)
- printf("waitpid error\n");
- }else if(pid == 0){ /*child*/
- printf("in.....");
- close(fd[1]);
- if(fd[0] != STDIN_FILENO){
- if(dup2(fd[0],STDIN_FILENO) != STDIN_FILENO){
- printf("dup2 error to stdin\n");
- exit(0);
- }
- }
- printf("in.....");
- execvp(cmd1,var1);
- printf("wrong command.\n");
- }
-
- }
- void onecmdout(int fd[2]){
- pid_t pid;
- int n,m;
- char line[1024];
- char ch;
- int fp;
- if((fp = open(file,O_WRONLY)) == -1){
- printf("can't open %s\n",file);
- exit(0);
- }
- if(pipe(fd) < 0){
- printf("pipe error\n");
- exit(0);
- }
- if((pid = fork()) < 0){
- printf("fork error\n");
- exit(0);
- } else if(pid > 0){ /*parent*/
- close(fd[1]);
- while((m = read(fd[0],&ch,1)) != 0){
- write(fp,&ch,1);
- }
-
- }else if(pid == 0){ /*child*/
- close(fd[0]);
- if(fd[1] != STDOUT_FILENO){
- if(dup2(fd[1],STDOUT_FILENO) != STDOUT_FILENO){
- printf("dup2 error to stdin\n");
- exit(0);
- }
- execvp(cmd1,var1);
- printf("wrong command.\n");
- }
- }
-
- }
- void ispipe(int fd[2])
- {
- pid_t pid,pid1;
- if(pipe(fd) < 0)
- printf("pipe error\n");
-
- /*deal with the command before '|'*/
-
-
- if(0){//尝试1
- if((pid = fork()) < 0)
- printf("fork error");
- if(pid > 0){
- close(fd[0]); //close read end
- dup2(fd[1],STDOUT_FILENO);
- execvp(cmd1,var1);
- } else if (pid == 0){
- close(fd[1]); //close write end
- dup2(fd[0],STDIN_FILENO);
- execvp(cmd2,var2);
-
- }
- }
- if(1){ 尝试2
- if((pid = fork()) < 0)
- printf("fork error");
- if(pid == 0) { /*child1*/
- close(fd[0]); /*close read end*/
- dup2(fd[1],STDOUT_FILENO);
- close(fd[1]);//aaaaaa
- execvp(cmd1,var1);
- }
-
- /*deal with the command after '|'*/
-
- if((pid1 = fork()) < 0)
- printf("fork error");
- if(pid1 == 0){ /*child2*/
- close(fd[1]); /*close write end*/
- dup2(fd[0],STDIN_FILENO);
- close(fd[0]);
- execvp(cmd2,var2);
- }
- //sleep(5);
-
- }
-
- }
- int main(int argc,char *argv[])
- {
- int fd[2];
- int filed;
- system("clear");
- for( ; ; ){
- getcmd();
- if(flag == 0) /*There is no pipe*/
- onecmd();
- else if(flag == 1) /*There is a pipe*/
- ispipe(fd);
- else if(flag == 2) /*There is a redirect '<'*/
- onecmdin(fd);
- else if(flag == 3) /*There is a redirect '>'*/
- onecmdout(fd);
- }
- }
复制代码 |
|