xv6-----shell

这是操作系统原理课程的第一个编程作业,补全shell的功能。

主要实现了基础的三类命令

  • 可执行的程序命令
  • 重定向命令
  • 管道命令

实现的"基类" (原谅我用了这个词)就是struct cmd这个结构体就一个成员,用于记录命令的类型.

三类, ' ' 表示可执行程序 '|' 表示管道命令,  '<'  和'>' 表示重定向类型.

每一个类型分别继承基类,派生出对应的三类结构体 

struct execcmd

struct redircmd

struct pipecmd

void runcmd(struct cmd * cmd);

这个函数是真正驱动调用实现shell的核心.负责调用系统接口函数 execv(), open(), close(), dup(), pipe()等等一系列函数,来完成我们既定的目标.

作业也就是补全这个函数.

这是个递归的函数!

下面是来自github上的代码,仅摘录runcmd函数

 1 void
 2 runcmd(struct cmd *cmd)
 3 {
 4   int p[2]; // used for pipe line in shell
 5   int r;    // return value
 6   struct execcmd *ecmd;
 7   struct pipecmd *pcmd;
 8   struct redircmd *rcmd;
 9 
10   if(cmd == 0)
11     exit(0);
12   
13   switch(cmd->type){
14   default:
15     fprintf(stderr, "unknown runcmd
");
16     exit(-1);
17 
18   case ' ':
19     ecmd = (struct execcmd*)cmd;
20     if(ecmd->argv[0] == 0)
21       exit(0);
22     //fprintf(stderr, "exec not implemented
");
23     // Your code here ...
24     if (access(ecmd->argv[0], S_IXUSR | S_IRUSR) == 0)
25     {
26         execv(ecmd->argv[0], ecmd->argv);
27     }
28     else
29     {
30         if(chdir("/bin/") < 0)
31         {
32             printf("change directory failed in line %d
", __LINE__);
33             exit(0);
34         }
35         execv(ecmd->argv[0], ecmd->argv);
36     }
37     fprintf(stderr, "execv() %s failed in line %d
", ecmd->argv[0], __LINE__);
38     break;
39 
40   case '>':
41   case '<':
42     rcmd = (struct redircmd*)cmd;
43     //fprintf(stderr, "redir not implemented
");
44     // Your code here ...
45     close(rcmd->fd);
46     if(open(rcmd->file, rcmd->mode) < 0)
47     {
48         fprintf(stderr, "Try to open :%s failed
", rcmd->file);
49         exit(0);
50     }
51     runcmd(rcmd->cmd);
52     break;
53 
54   case '|':
55     pcmd = (struct pipecmd*)cmd;
56     //fprintf(stderr, "pipe not implemented
");
57     // Your code here ...
58     if(pipe(p) < 0)
59     {
60         fprintf(stderr, "call syscall pipe() failed in line %d
", __LINE__);
61         exit(0);
62     }
63 
64     if(fork1() == 0)
65     {
66         close(1);
67         dup(p[1]);
68         close(p[0]);
69         close(p[1]);
70         runcmd(pcmd->left);
71     }
72 
73     if(fork1() == 0)
74     {
75         close(0);
76         dup(p[0]);
77         close(p[0]);
78         close(p[1]);
79         runcmd(pcmd->right);
80     }
81 
82     close(p[0]);
83     close(p[1]);
84     wait();
85     wait();
86     break;
87   }    
88 
89   exit(0);
90 }

有兴趣可以点击查看详情

原文地址:https://www.cnblogs.com/tjulym/p/4973496.html