操作系统实验指导书新 - 图文 联系客服

发布时间 : 星期六 文章操作系统实验指导书新 - 图文更新完毕开始阅读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