发布时间 : 星期六 文章操作系统实验指导书新 - 图文更新完毕开始阅读3078b7bf376baf1ffd4fad39
printf(\ return -1; }
if (is_out != -1) /*使用dup2函数将标准输出重定向到fd_out上,dup2(int oldfd,int newfd)实现的
*是把oldfd所指的文件描述符复制到newfd。若newfd为一已打开的文件描述词, *则newfd所指的文件会先被关闭,dup2复制的文件描述词与原来的文件描述词 *共享各种文件状态*/
if(dup2(fd_out,STDOUT_FILENO)==-1){
printf(\ exit(1); } if (is_in != -1)
if(dup2(fd_in,STDIN_FILENO)==-1){
printf(\ exit(1); }
execv(buffer,argv); } else
if (is_back == 0) /*run on the TOP*/ waitpid(pid,&status,0);
for (i=0;i if (is_in != -1){ free(filename[is_in]); close(fd_in); } if (is_out != -1){ free(filename[is_out]); close(fd_out); } return 0; } int pipel(char *input,int len) { char *argv[2][30]; 35 int i,j,k,count,is_back = 0; int li_comm = 0,fd[2],fpip[2]; char lc_char,lc_end[1]; pid_t child1,child2; /*管道的命令解析过程*/ for (i = 0,j = 0,k = 0;i <= len;i++){ if (input[i]== ' ' || input[i] == '\\t' || input[i] == '\\0' || input[i] == '|'){ if (input[i] == '|' ) /*管道符号*/ { if (j > 0) { buffer[j++] = '\\0'; /*因为管道连接的是两个指令,所以用二维数组指针来存放命令和参数, *li_comm是表示第几个指令*/ argv[li_comm][k] = (char *) malloc(sizeof(char)*j); strcpy(argv[li_comm][k++],buffer); } argv[li_comm][k++] = (char *) 0; /*遇到管道符,第一个指令完毕,开始准备接受第二个指令*/ li_comm++; count = k; k=0;j=0; } if (j == 0) continue; else { buffer[j++] = '\\0'; argv[li_comm][k] = (char *) malloc(sizeof(char)*j); strcpy(argv[li_comm][k],buffer); k++; } j = 0; /*initate*/ } else{ if (input[i] == '&' && input[i+1] == '\\0'){ is_back = 1; continue; } buffer[j++] = input[i]; } } argv[li_comm][k++] = (char *) 0; 36 if (is_fileexist(argv[0][0]) == -1 ){ printf(\ for(i=0;i /*指令解析结束*/ /*建立管道*/ if (pipe(fd) == -1 ){ printf(\ return -1; } /*创建第一个子进程执行管道符前的指令,并将输出写到管道*/ if ((child1 = fork()) ==0){ /*关闭读端*/ close(fd[0]); if (fd[1] != STDOUT_FILENO){ /*将标准输出重定向到管道的写入端,这样该子进程的输出就写入了管道*/ if (dup2(fd[1],STDOUT_FILENO) == -1){ printf(\ return -1; } /*关闭写入端*/ close(fd[1]); } execv(buffer,argv[0]); } else{ /*父进程*/ /*先要等待写入管道的进程结束*/ waitpid(child1,&li_comm,0); /*然后我们必须写入一个结束标记,告诉读管道进程数据到这里就完了*/ lc_end[0] = 0x1a; write(fd[1],lc_end,1); close(fd[1]); if (is_fileexist(argv[1][0]) == -1 ){ printf(\ for(i=0;i 37 /*创建第二个进程执行管道符后的指令,并从管道读输入流 */ if ((child2 = fork()) == 0){ if (fd[0] != STDIN_FILENO){ /*将标准输入重定向到管道读入端*/ if(dup2(fd[0],STDIN_FILENO) == -1){ printf(\ return -1; } close(fd[0]); } execv(buffer,argv[1]); } else /*父进程*/ if (is_back == 0) waitpid(child2,NULL,0); } for (i=0;i 四.设计实验 1.实验要求 1)利用C语言编写一个微型命令解释程序,接收并解释以下命令: dir: 列当前目录 cop 文件1 文件2: 拷贝文件 era 文件名: 删除文件 dis 字符串: 显示字符串 end: 结束并退出 2)进行命令合法性检查,若不合法,显示出错信息,等待重新输入; 3)命令前后有空格为合法命令。 2.程序源代码(学生自行设计) 38