这是操作系统原理课程的第一个编程作业,补全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\n"); 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\n"); 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\n", __LINE__); 33 exit(0); 34 } 35 execv(ecmd->argv[0], ecmd->argv); 36 } 37 fprintf(stderr, "execv() %s failed in line %d\n", ecmd->argv[0], __LINE__); 38 break; 39 40 case ‘>‘: 41 case ‘<‘: 42 rcmd = (struct redircmd*)cmd; 43 //fprintf(stderr, "redir not implemented\n"); 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\n", 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\n"); 57 // Your code here ... 58 if(pipe(p) < 0) 59 { 60 fprintf(stderr, "call syscall pipe() failed in line %d\n", __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 }
时间: 2024-12-21 02:11:26