期末操作系统实验课程设计.docx
- 文档编号:11323659
- 上传时间:2023-02-26
- 格式:DOCX
- 页数:12
- 大小:17.14KB
期末操作系统实验课程设计.docx
《期末操作系统实验课程设计.docx》由会员分享,可在线阅读,更多相关《期末操作系统实验课程设计.docx(12页珍藏版)》请在冰豆网上搜索。
期末操作系统实验课程设计
操作系统实验课程设计
(二)(参照实验五)
学院:
计算机科学与工程专业:
信息管理工作与信息系统
学号:
18姓名:
丁建东
一、实验题目:
设计一个Shell解释器
二、实验目的:
本设计的主要目的在于学会如何在Unix系统下创建进程和管理进程。
三、实验内容:
实现一个简单的shell(命令行解释器),类似于bash,csh等。
要求实现的shell支持以下内部命令:
1.cd<目录>
更改当前的工作目录到另一个<目录>。
如果<目录>未指定,输出当前工作目录。
如果<目录>不存在,要求有适当的错误信息提示。
改命令应能够改变PWD的环境变量。
2.echo<内容>
显示echo后的内容且换行。
3.help
简短概要地输出你的shell的使用方法和基本功能。
4.jobs
输出shell当前的一系列子进程,要求提供子进程的命名和PID号。
5.quit,exit,bye
退出shell。
所有的内部命令应当优于在$PATH中同名的程序。
任何非内部命令必须请求shell创建一个新进程,且该子进程执行指定的程序。
这个新进程必须继承shell的环境变量和指定的命令行参数。
要求实现的shell支持以下内部命令:
BatchProcessing如果shell启动带有一个文件名作为参数,打开该文件并执行文件里所有命令。
待所有进程全部结束退出shell。
四、实验思路:
1.所用到的系统函数
(1)打开目录
voidcd()
API调用:
intchdir(dir);getcwd(dir,dir_max);
实现:
改变当前目录,并判断目录是否存在。
(2)回应
voidecho()
实现:
用户输入字符串,以回车结束输入。
charecho_string[echo_len][echo_max];//用户输入命令,以空格符隔开,存为字符串数组
按顺序输出用户输入的字符串。
(3)输出当前子进程
Voidjobs()
API调用:
shmget(),shmat()
实现:
开辟一个共享内存区,一旦创建一个子进程,就把该进程的进程ID和名字记字共享区里,在子进程结束的时候消除该记录。
这样,调用jobs时只要读取共享区里的记录并输出就可以知道当前运行的子进程了。
(4)输出当前路径
voidpwd()
API调用:
getcwd();
五、程序流程图
。
。
。
六、程序代码
#include<>
#include<>
#include<>
#include<>
#include
#include
#include<>
#include<>
#defineMAXLENGTH25
#defineSUBLENGTH5
#defineLINELENGTH40
#defineECHO"myshell#"
#defineQUIT"exit"
char*readline;
typedefenum
{
EXEC,REDI,REDIS,PIPE,NOHUP,BACKGROUND
}TokenType;
typedefvoid(*fun)(char*);
voidanalyse(void);
voidexec(char*);
voidredi(char*);
voidpiped(char*);
voidbgtask(char*);
sigset_t*set;
intmain(void)
{
readline=(char*)malloc(MAXLENGTH*sizeof(char));
set=(sigset_t*)malloc(sizeof(sigset_t));
sigemptyset(set);
if(sigaddset(set,SIGINT)==-1)
{
printf("sigseterror1~!
\n");
exit(0);
}
if(sigprocmask(SIG_BLOCK,set,NULL)==-1)
{
printf("sigseterror2~!
\n");
exit(0);
}
while
(1)
{
//signal(SIGINT,SIG_IGN);//ctrl+cisignored
fputs(ECHO,stdout);//printfecho
gets(readline);//getsreadline
if(strncmp(readline,QUIT,4)==0)//equalexitthenexit
{
free(readline);
return0;
}
analyse();//analyse
}
}
//analysethereadline
voidanalyse(void)
{
TokenTypetype=EXEC;//commandstyle
inti=0;
charc;
//functionmapping
funfun_array[]={
exec,
redi,
NULL,
piped,
NULL,
bgtask
};
//the'nohup'isamazing
/*
//testifcontainsnohup
if(!
strncmp(readline,"nohup",6))
{
printf("nohup~!
\n");
signal(SIGHUP,SIG_IGN);//SIGHUPisignored
intj=6;
c=*(readline+j);
//dealwiththereadline
while(c!
='\0')
{
*(readline+i)=c;
i++;
j++;
c=*(readline+j);
}
*(readline+i)='\0';
i=0;
}*/
c=*(readline+i);
//controltheTokenType
while(c!
='\0')
{
if(c=='>')
{
type=REDI;
*(readline+i)='+';
}
elseif(c=='<')
{
type=REDIS;
*(readline+i)='+';
}
elseif(c=='|')
{
type=PIPE;
*(readline+i)='+';
}
elseif(c=='&')
{
type=BACKGROUND;
*(readline+i)='+';
}
i++;
c=*(readline+i);
}
//withthefunctionarray,doit
(*fun_array[type])(readline);
}
//executesimplecommand
voidexec(char*p)
{
printf("%s\n",p);
char**tmp=(char**)malloc(SUBLENGTH*sizeof(char*));
intnum=0;
pid_tpid;
//splitthestring
tmp[num]=strtok(p,"");
while(tmp[++num]=strtok(NULL,""))
;
pid=fork();
if(pid==0)
{
if(sigprocmask(SIG_UNBLOCK,set,NULL)==-1)
{
printf("sigseterror~!
\n");
exit(0);
}
//executeit
interror=execvp(tmp[0],tmp);
if(error<0)
{
printf("Commandnotfound~!
\n");
//exit(0);
}
free(tmp);
exit(0);
}
else
wait(NULL);
}
//commandcontains'>'
voidredi(char*p)
{
char*str=strtok(p,"+");
char*file_name=strtok(NULL,"");
char**tmp=(char**)malloc(SUBLENGTH*sizeof(char*));
intnum=0;
intfile,file_old,file_new;
pid_tpid;
tmp[num]=strtok(str,"");
while(tmp[++num]=strtok(NULL,""))
;
//openthefile
file=open(file_name,O_WRONLY|O_CREAT);
if(file==-1)
{
printf("openfileerror!
\n");
free(tmp);
}
//inordertorecover
file_old=dup(STDOUT_FILENO);
//redirectthestream
file_new=dup2(file,STDOUT_FILENO);
if(file_new==-1)
{
printf("duperror~!
\n");
close(file);
return;
}
pid=fork();
if(pid==0)
{
interror=execvp(tmp[0],tmp);
if(error<0)
{
printf("Commandisnotfound~!
\n");
exit(0);
}
close(file);
free(tmp);
exit(0);
}
else
{
wait(NULL);
//recoverthestream
if(dup2(file_old,file_new)==-1)
{
printf("dup2error\n");
}
}
}
//commandcontains'|'
voidpiped(char*p)
{
char*str1=strtok(p,"+");
char*str2=strtok(NULL,"+");
charline[LINELENGTH];
//usepipeimplementsthe'|'
FILE*in=popen(str1,"r");
FILE*out=popen(str2,"w");
if(in==NULL||out==NULL)
{
printf("popenerror~!
\n");
return;
}
//readthestringandwritetoout
while(fgets(line,LINELENGTH,in)!
=NULL)
if(fputs(line,out)==EOF)
printf("fputserror~!
\n");
pclose(in);
pclose(out);
}
//implementsbackgroundtask
voidbgtask(char*p)
{
char*str=strtok(p,"+");
char**tmp=(char**)malloc(SUBLENGTH*sizeof(char*));
intnum=0;
pid_tpid;
//split
tmp[num]=strtok(str,"");
while(tmp[++num]=strtok(NULL,""));
if((pid=fork())<0)
{
printf("forkerror~!
\n");
return;
}
if(pid==0)
{
if(fork())
exit(0);//parentdied
else
{
interror=execvp(tmp[0],tmp);
if(error<0)
{
printf("commamdnotfound");
exit(0);
}
exit(0);
}
}
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 期末 操作系统 实验 课程设计