期末 操作系统实验课程设计
- 格式:doc
- 大小:57.00 KB
- 文档页数:15
操作系统课程设计报告题目:一个小型的操作系统班级:计122(杏)学号:1213023075姓名:贾苏日期:2014/06/231.实验平台(1)软件平台:开发系统平台:Windows 7 (64)Microsoft visual c++ 6.0测试系统平台:Windows 7 (64)(2)硬件平台:cpu:AMD A6-3420 APU内存:4GB硬盘:500G2.所需实现的功能及相应的阐述:(1)进程调度管理为了贴切现实中的os,采用RR(轮转调度算法),且不提供用户显式的选择调度算法,即对用户是透明的。
现实中的处理器主频为1Ghz~3Ghz,选取中间点为1.5Ghz,得时间片大小为0.7ns ,为方便计算*10,则时间片大小定为7ns。
假设进程之间的调度和切换不耗费cpu时间。
(2)死锁的检测与处理检测当然采用的是银行家算法处理:让用户选择kill一个进程,释放他所占有的所有资源。
(3)虚拟分页调度管理虚拟分页:给出的是逻辑值访问磁盘将那个数据块放入到内存中内存中的地址采用一定的算法相对应于磁盘的地址。
特规定访存采用的是按字节寻址内存的大小128KB外存的大小1MB即整个系统可以提供1MB的逻辑地址空间供进程进行访问(在地址总线足够扫描内存的情况下)。
虚拟地址映射采用:直接映射法规定的8kB为一个页面,故内存有16个页面,外存有128个页面。
如果产生了内存已满,便会产生缺页中断,淘汰采用FIFO算法,利用一个队列来做。
部分内外存的对应表0 0,128,2*128+0.......1 1,129,2*128+1.......2 2,130,2*128+2.......16 127,128+16,2*128+16.........(4)I/O中断处理设中断来自两个方面:1.DMA输送开始和结束时的中断设定一个宏定义为DMA一次传输的数据量的大小->DmaNum 假定为10kb每次DMA开始:耗费1ns cpu时间进行中断处理DMA 结束:耗费2ns cpu 时间进行中断处理由操作系统课程知,DMA 传输数据时不需要CPU 的干预。
《操作系统课程设计》实验报告学号:姓名:苏州大学计算机科学与技术学院2014年9月操作系统课程设计实验报告目录目录 (1)一、实验环境 (2)二、实验报告总体要求 (2)实验一编译L INUX内核 (3)实验二观察L INUX行为 (7)实验三进程间通信 (14)操作系统课程设计实验报告一、实验环境Linux平台◆硬件平台:普通PC机硬件环境。
◆操作系统:Linux环境,例如,红旗Linux或Red Hat Linux;启动管理器使用GRUB。
◆编译环境:伴随着操作系统的默认gcc环境。
◆工作源码环境:一个调试的内核源码,版本不低于2.4.20。
二、实验报告总体要求在2013年11月25日前提交实验报告。
实验报告至少要求包含以下内容:1.引言:概述本次实验所讨论的问题,工作步骤,结果,以及发现的意义。
2.问题提出:叙述本篇报告要解决什么问题。
注意不可以抄写实验要求中的表述,要用自己的话重新组织我们这里所提出的问题。
3.解决方案:叙述如何解决自己上面提出的问题,可以用小标题 3.1,3.2…等分开。
这是实验报告的关键部分,请尽量展开来写。
注意,这部分是最终课程设计的基本分的部分。
这部分不完成,本课程设计不会及格。
4.实验结果:按照自己的解决方案,有哪些结果。
结果有异常吗?能解释一下这些结果吗?同别人的结果比较过吗?注意,这部分是实验报告出彩的地方。
本课程设计要得高分,应该在这部分下功夫。
5.结束语:小结并叙述本次课程设计的经验、教训、体会、难点、收获、为解决的问题、新的疑惑等。
6.附录:加了注释的程序清单,注释行数目至少同源程序行数目比1:2,即10行源程序,至少要给出5行注释。
操作系统课程设计实验报告实验一编译Linux内核实验时间6小时实验目的认识Linux内核的组成,掌握配置、编译、安装Linux内核的步骤。
实验目标下载2.6.19或更新的Linux内核,配置该内核使其支持NTFS,并在新的内核中修改其版本为Linux NameTestKernel x.x.x,其中,Name是你的名字(汉语拼音);x.x.x是新内核的版本号,最后在你的机器上编译安装这个新内核。
操作系统课程设计一、课程目标知识目标:1. 理解操作系统的基本概念、功能、类型和结构,掌握操作系统的五大核心功能模块(处理器管理、存储器管理、设备管理、文件管理、用户接口);2. 掌握操作系统的发展历程、主要操作系统(如Windows、Linux、Mac OS)的特点及应用场景;3. 了解操作系统的设计与实现原理,包括进程管理、内存管理、设备管理、文件系统等关键技术;4. 学会使用操作系统提供的命令行或图形界面进行基本的系统操作与维护。
技能目标:1. 培养学生对操作系统的实际操作能力,能够熟练使用至少一种操作系统进行日常管理与维护;2. 培养学生运用操作系统原理解决实际问题的能力,如分析系统性能、诊断故障、优化配置等;3. 提高学生的编程能力,使其能够编写简单的系统程序或脚本,实现特定功能。
情感态度价值观目标:1. 培养学生对操作系统的兴趣,激发学生学习计算机科学的热情;2. 培养学生的团队合作意识,使其在讨论、分析、解决问题的过程中学会倾听、交流、协作;3. 培养学生具备良好的信息素养,关注操作系统领域的最新发展,增强信息安全意识。
课程性质:本课程为计算机科学与技术专业(或相关领域)的必修课,具有较强的理论性和实践性。
学生特点:学生已具备一定的计算机基础知识,具有较强的学习兴趣和动手能力,但可能对操作系统原理的理解和应用尚有不足。
教学要求:注重理论与实践相结合,以案例驱动、任务导向的方式进行教学,注重培养学生的实际操作能力和问题解决能力。
通过本课程的学习,使学生能够掌握操作系统的基本原理,提高实际应用水平,为后续专业课程学习打下坚实基础。
二、教学内容1. 操作系统概述:介绍操作系统的基本概念、功能、类型,比较不同操作系统的特点,分析操作系统的发展趋势。
教材章节:第一章 操作系统概述2. 进程与线程管理:讲解进程与线程的概念、状态与转换,进程调度算法,同步与互斥,死锁与饥饿问题。
教材章节:第二章 进程管理3. 存储管理:介绍内存分配与回收策略,虚拟内存技术,页面置换算法,内存保护机制。
《操作系统》课程设计一、课程目标知识目标:1. 让学生掌握操作系统的基本概念,包括进程、线程、内存管理、文件系统等核心知识;2. 了解操作系统的历史发展,掌握不同类型操作系统的特点及使用场景;3. 掌握操作系统的性能评价方法和常用的调度算法。
技能目标:1. 培养学生运用操作系统知识解决实际问题的能力,如分析系统性能瓶颈、优化系统资源分配等;2. 培养学生具备基本的操作系统编程能力,如进程创建、线程同步、文件操作等;3. 提高学生的团队协作能力和沟通能力,通过小组讨论和项目实践,学会共同解决问题。
情感态度价值观目标:1. 培养学生对操作系统学科的兴趣,激发学生的学习热情,使其形成积极向上的学习态度;2. 培养学生具备良好的信息素养,尊重知识产权,遵循法律法规;3. 培养学生的创新精神和批判性思维,敢于质疑、勇于探索,形成独立思考的能力。
课程性质:本课程为计算机科学与技术专业的核心课程,旨在让学生掌握操作系统的基本原理和实现方法,提高学生的系统分析和编程能力。
学生特点:学生具备一定的编程基础和计算机系统知识,具有较强的逻辑思维能力和动手实践能力。
教学要求:结合学生特点和课程性质,注重理论与实践相结合,通过案例分析和项目实践,帮助学生将所学知识内化为具体的学习成果。
在教学过程中,关注学生的学习进度和反馈,及时调整教学策略,确保课程目标的实现。
二、教学内容1. 操作系统概述:介绍操作系统的定义、发展历程、功能、类型及特点,对应教材第一章内容。
- 操作系统的起源与发展- 操作系统的功能与类型- 操作系统的主要特点2. 进程与线程:讲解进程与线程的概念、状态、调度算法,对应教材第二章内容。
- 进程与线程的定义与区别- 进程状态与转换- 进程调度算法3. 内存管理:分析内存管理的基本原理、策略和技术,对应教材第三章内容。
- 内存分配与回收策略- 虚拟内存技术- 页面置换算法4. 文件系统:介绍文件系统的基本概念、结构、存储原理,对应教材第四章内容。
操作系统实验
(课程设计)实验报告
学院
专业
班级/学号
学生姓名
成绩
实验地点_
实验日期___ __
指导教师_____ ___ _____
(课程上机)实验报告
1.实验名称、实验目的、实验内容、实验要求由教师确定,实验前由教师事先填好,然后作为实验报告模版供学生使用;
2.实验准备由学生在实验或上机之前填写,教师应该在实验前检查;
3.实验过程由学生记录实验的过程,包括操作过程、遇到哪些问题以及如何解决等;
4.实验总结由学生在实验后填写,总结本次实验的收获、未解决的问题以及体会和建议等;
5.源程序、代码、具体语句等,若表格空间不足时可作为附录另外附页。
操作系统实验报告2学院:计算机科学与技术学院班级:计091学号:姓名:时间:2011/12/30目录1.实验名称 (3)2.实验目的 (3)3.实验内容 (3)4.实验要求 (3)5.实验原理 (3)6.实验环境 (4)7.实验设计 (4)数据结构设计 (4)算法设计 (6)功能模块设计 (7)8.实验运行结果 (8)9.实验心得 (9)附录:源代码部分 (9)一、实验名称:用C++实现银行家算法二、实验目的:通过自己编程来实现银行家算法,进一步理解银行家算法的概念及含义,提高对银行家算法的认识,同时提高自己的动手实践能力;各种死锁防止方法能够阻止发生死锁,但必然会降低系统的并发性并导致低效的资源利用率;死锁避免却与此相反,通过合适的资源分配算法确保不会出现进程循环等待链,从而避免死锁;本实验旨在了解死锁产生的条件和原因,并采用银行家算法有效地防止死锁的发生;三、实验内容:利用C++,实现银行家算法四、实验要求:1.完成银行家算法的设计2.设计有n个进程共享m个系统资源的系统,进程可动态的申请和释放资源,系统按各进程的申请动态的分配资源;五、实验原理:系统中的所有进程放入进程集合,在安全状态下系统收到进程的资源请求后,先把资源试探性的分配给它;之后,系统将剩下的可用资源和进程集合中的其他进程还需要的资源数作比较,找出剩余资源能够满足的最大需求量的进程,从而保证进程运行完毕并归还全部资源;这时,把这个进程从进程集合中删除,归还其所占用的所有资源,系统的剩余资源则更多,反复执行上述步骤;最后,检查进程集合,若为空则表明本次申请可行,系统处于安全状态,可以真正执行本次分配,否则,本次资源分配暂不实施,让申请资源的进程等待;银行家算法是一种最有代表性的避免的算法;在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待;为实现银行家算法,系统必须设置若干;要解释银行家算法,必须先解释操作系统安全状态和不安全状态;安全序列是指一个进程序列{P1,…,Pn}是安全的,如果对于每一个进程Pi1≤i≤n,它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj j < i 当前占有资源量之和;安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态;安全状态一定是没有死锁发生;不安全状态:不存在一个安全序列;不安全状态不一定导致死锁;我们可以把看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款;为保证资金的安全,银行家规定:1 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;2 顾客可以分期贷款,但贷款的总数不能超过最大需求量;3 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;4 当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金.操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配;当进程在执行中继续申请资源时,先测试该进程本次申请的资源数是否超过了该资源所剩余的总量;若超过则拒绝分配资源,若能满足则按当前的申请量分配资源,否则也要推迟分配;六、实验环境:Win-7系统Visual C++七、实验设计:1.数据结构设计定义结构体:struct Process0, 0, 0;}}};class DataInit法设计class FindSafeListdb->available; db->pdb->ruleri.currentAvail db->pdb->ruleri-1.currentAvail;db->pdb->ruleri-1.allocation;db->pdb->ruleri.currentAvail{ return false; }db->sum{ return false; }}return true; laim_allocation{ return 1; }Source sdb->pi.allocation; db->ask;db->pi.db->ask;ifexsitSafeListdb db->ask;db->pi.db->ask;return 2;}db->0,0,0; 能模块设计class Data0, 0, 0;}}};class DataInitr1,r2,r3;cout<<'p'<<i<<" max allocationclaimR1,R2,R3: ";r1,r2,r3;r1=db->pi.>pi.;pi.;r3=db->pi.>pi.;db->pi.r1, r2, r3;}}};class Displaylaim;cout<<"\t\t";displaySourcepi.allocation;cout<<endl;}cout<<endl;}void displaySafeListData db urrentAvail;cout<<" ";displaySourcedb->pdb->ruleri.claim;cout<<" ";displaySourcedb->pdb->ruleri.allocation;cout<<" ";displaySourcedb->pdb->ruleri.claim_allocation;cout<<" true";cout<<endl;}}void displayAskResultData db,int n db->available;db->pdb->ruleri.currentAvail db->pdb->ruleri-1.currentAvail;db->pdb->ruleri-1.allocation;db->pdb->ruleri.currentAvail{ return false; }db->sum{ return false; }}return true; laim_allocation{ return 1; }Source sdb->pi.allocation; db->ask;db->pi.db->ask;ifexsitSafeListdb db->ask;db->pi.db->ask;return 2;}db->0,0,0; //找到安全序列,将请求资源置零,返回3return 3;}};void main{Data db;db=new Data;ifdb{ cout<<"errorno enough memory space"; return; } DataInit dataInit;db; //设置进程个数db; //设置系统总资源量db; //设置当前系统可获得资源量db; //设置t0时刻进程基本状态Display display;FindSafeList findSafeList;int r1=0,r2=0,r3=0;int c;db->r1,r2,r3; //设置请求资源为0,即无请求c=db,0; //寻找安全序列,返回结果ifc=3{ cout<<"t0时刻的进程组不存在安全序列\n"; return; }int choice=1;int pi;whilechoice{cout<<"\n 选择操作:\n 1 查看进程情况\n 2 请求分配资源\n 0 退出\n ";cin>>choice;switchchoice{case 1:{cout<<"当前资源量availableR1,R2,R3:\n ";db->available;cout<<endl;cout<<"\n当前进程资源分配情况piR1,R2,R3: \n";cout<<" 进程\tclaim\t\tallocation\n";db->p,db->pLength;break;}case 2:{cout<<"输入请求资源进程序号:";cin>>pi;cout<<"输入请求资源R1,R2,R3: 0,0,0表示当前进程组无请求\n";cin>>r1>>r2>>r3;db->r1,r2,r3;c=db,pi;db,c;cout<<endl;break;}case 0:{ break; }default:{ cout<<"input errortry again\n"; break; }}}}。
linux期末课程设计一、教学目标本课程的学习目标包括以下三个方面:1.知识目标:学生需要掌握Linux操作系统的基本概念、原理和常用的命令行操作。
具体包括Linux的历史、特点和常用发行版;文件系统结构;基本命令行操作;用户和权限管理;进程管理;网络配置和应用服务等。
2.技能目标:学生能够熟练使用Linux操作系统,进行日常的系统管理和维护工作。
具体包括文件操作、目录管理、文本处理、软件安装和更新、系统设置和网络配置等。
3.情感态度价值观目标:学生通过课程的学习,能够理解Linux开源精神的重要性,培养团队合作和分享的意识,提高自主学习和解决问题的能力。
二、教学内容本课程的教学内容主要包括以下几个部分:1.Linux概述:介绍Linux操作系统的起源、发展和特点,以及常用的Linux发行版。
2.文件系统:讲解Linux的文件系统结构,包括目录、文件权限和文件操作命令等。
3.命令行操作:深入学习Linux的命令行操作,包括基本命令、文本处理命令和软件包管理命令等。
4.用户和权限管理:介绍Linux的用户管理、组管理和文件权限控制等知识。
5.进程管理:讲解Linux的进程概念、进程控制命令和进程监控工具等。
6.网络配置:包括网络配置命令、网络文件共享和远程登录等知识。
7.应用服务:介绍Linux下的常用服务,如Apache、MySQL和Samba 等。
三、教学方法本课程采用多种教学方法,以激发学生的学习兴趣和主动性:1.讲授法:讲解Linux的基本概念、原理和命令操作。
2.案例分析法:通过实际案例,引导学生学会解决实际问题。
3.实验法:安排实验课,让学生亲自动手操作,加深对知识的理解和记忆。
4.小组讨论法:学生进行小组讨论,培养团队合作和沟通能力。
四、教学资源本课程的教学资源包括以下几个方面:1.教材:选用权威、实用的Linux教材,为学生提供系统的学习资料。
2.参考书:提供丰富的参考书籍,方便学生深入研究。
UCOSII操作系统课程设计一、课程目标知识目标:1. 理解UCOSII操作系统的基本原理和核心概念,包括任务管理、时间管理、通信与同步机制;2. 掌握UCOSII的移植方法和配置过程,学会在不同硬件平台上搭建UCOSII 操作系统环境;3. 学会使用UCOSII提供的API进行多任务编程,了解实时操作系统的任务调度和资源管理策略。
技能目标:1. 能够运用C语言在UCOSII环境下编写多任务应用程序,实现任务间的同步与通信;2. 能够分析并解决实际嵌入式系统开发中与操作系统相关的问题,提高系统稳定性和可靠性;3. 掌握UCOSII调试技巧,能够运用调试工具对操作系统运行状态进行跟踪和分析。
情感态度价值观目标:1. 培养学生对操作系统知识的好奇心和探索精神,激发学习兴趣和热情;2. 培养学生具备良好的团队合作精神和沟通能力,提高解决实际问题的能力;3. 增强学生的创新意识,鼓励他们在实际项目中积极尝试和应用所学知识。
课程性质:本课程为高年级专业课,以实际应用为导向,注重理论与实践相结合。
学生特点:学生已具备一定的C语言编程基础和嵌入式系统知识,具有较强的学习能力和实践能力。
教学要求:教师需采用项目驱动教学法,引导学生通过实际案例掌握UCOSII 操作系统的应用与开发。
在教学过程中,关注学生的个体差异,提供个性化指导,确保课程目标的实现。
同时,注重培养学生的自主学习能力和创新能力,为将来的职业发展打下坚实基础。
二、教学内容1. UCOSII操作系统概述:介绍实时操作系统的基本概念、特点及应用场景,引出UCOSII的背景、架构和优势。
教材章节:第一章 实时操作系统概述2. UCOSII内核原理:讲解UCOSII的核心组件,包括任务管理、时间管理、通信与同步机制等。
教材章节:第二章 UCOSII内核原理3. UCOSII移植与配置:介绍在不同硬件平台上移植和配置UCOSII的方法,以实际案例为例进行讲解。
实践课设计报告课程名称操作系统课程设计模拟设计内存管理中的地址题目转换(动态分区、页式十进制)学院班级学号姓名指导教师年月日课程设计任务书学生姓名:专业班级:指导教师:工作单位:题目: 模拟设计内存管理中的地址转换(动态分区、页式十进制)初始条件:1.预备内容:阅读操作系统的内存管理章节内容,理解动态分区、页式、段式和段页式存储管理的思想及相应的分配主存的过程。
2.实践准备:掌握一种计算机高级语言的使用。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.下列内部存储器管理中地址转换,在完成指定存储管理技术中的地址转换基础上还可以选择其它内部存储器管理中的地址转换进行模拟设计并实现:⑴动态分区方案,用最先适用算法对作业实施内存分配,然后把作业地址空间的某一逻辑地址转换成相应的物理地址。
能够处理以下的情形:输入某一逻辑地址,程序能判断地址的合法性,如果合法,计算并输出相应的物理地址。
如果不能计算出相应的物理地址,说明原因。
⑵页式存储管理中逻辑地址到物理地址的转换(十进制)。
能够处理以下的情形:输入某一十进制逻辑地址,能检查地址的合法性,如果合法进行转换,否则显示“地址非法”;物理地址用十进制表示。
⑶页式存储管理中逻辑地址到物理地址的转换(八进制)。
能够处理以下的情形:输入某一八进制逻辑地址,能检查地址的合法性,如果合法进行转换,否则显示“地址非法”;物理地址用八进制表示。
⑷页式存储管理中逻辑地址到物理地址的转换(十六进制)。
能够处理以下的情形:输入某一十六进制逻辑地址,能检查地址的合法性,如果合法进行转换,否则显示“地址非法”;物理地址用十六进制表示。
⑸段式存储管理中逻辑地址到物理地址的转换。
能够处理以下的情形:指定内存的大小,进程的个数,每个进程的段数及段大小;能检查地址的合法性,如果合法进行转换,否则显示地址非法的原因。
⑹段页式存储管理中逻辑地址到物理地址的转换。
操作系统实验课程设计(二)(参照实验五)学院:计算机科学与工程专业:信息管理工作与信息系统学号:2008142118 姓名:丁建东一、实验题目:设计一个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支持以下内部命令:Batch Processing 如果shell启动带有一个文件名作为参数,打开该文件并执行文件里所有命令。
待所有进程全部结束退出shell。
四、实验思路:1.所用到的系统函数(1)打开目录void cd()API调用:int chdir(dir);getcwd(dir,dir_max);实现:改变当前目录,并判断目录是否存在。
(2)回应void echo()实现:用户输入字符串,以回车结束输入。
char echo_string[echo_len][echo_max];//用户输入命令,以空格符隔开,存为字符串数组按顺序输出用户输入的字符串。
(3)输出当前子进程Void jobs()API调用:shmget(),shmat()实现:开辟一个共享内存区,一旦创建一个子进程,就把该进程的进程ID和名字记字共享区里,在子进程结束的时候消除该记录。
这样,调用jobs时只要读取共享区里的记录并输出就可以知道当前运行的子进程了。
(4)输出当前路径void pwd()API调用:getcwd();五、程序流程图。
六、程序代码#include <stdio.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#define MAXLENGTH 25#define SUBLENGTH 5#define LINELENGTH 40#define ECHO "myshell#"#define QUIT "exit"char * readline;typedef enum{EXEC,REDI,REDIS,PIPE,NOHUP,BACKGROUND }TokenType;typedef void (*fun)(char *);void analyse(void);void exec(char*);void redi(char*);void piped(char*);void bgtask(char*);sigset_t *set;int main(void){readline = (char *) malloc(MAXLENGTH*sizeof(char)); set = (sigset_t *)malloc(sizeof(sigset_t));sigemptyset(set);if( sigaddset(set,SIGINT) == -1){printf("sigset error1~!\n");exit(0);}if(sigprocmask(SIG_BLOCK,set,NULL) == -1){printf("sigset error2~!\n");exit(0);}while(1){//signal(SIGINT,SIG_IGN); //ctrl+c is ignoredfputs(ECHO,stdout);//printf echogets(readline);//gets readlineif(strncmp(readline,QUIT,4) == 0) //equal exit then exit {free(readline);return 0;}analyse();//analyse}}//analyse the readlinevoid analyse(void){TokenType type = EXEC; //command style int i = 0;char c ;//function mappingfun fun_array[] ={exec,redi,NULL,piped,NULL,bgtask};//the 'nohup ' is amazing//test if contains nohupif(!strncmp(readline,"nohup ",6)){printf("nohup~!\n");signal(SIGHUP,SIG_IGN);// SIGHUP is ignored int j = 6;c = *(readline+j);//deal with the readlinewhile(c != '\0'){*(readline+i) = c;i++;j++;c = *(readline+j);}*(readline+i) = '\0';i = 0;}*/c = *(readline+i);//control the TokenTypewhile(c != '\0')if(c == '>'){type = REDI;*(readline+i) = '+';}else if(c == '<'){type = REDIS;*(readline+i) = '+';}else if(c == '|'){type = PIPE;*(readline+i) = '+';}else if(c == '&'){type = BACKGROUND;*(readline+i) = '+';}i++;c = *(readline+i);}//with the function array ,do it(*fun_array[type])(readline);}//execute simple commandvoid exec(char * p){printf("%s\n",p);char ** tmp = (char **)malloc(SUBLENGTH*sizeof(char*)); int num = 0;pid_t pid;//split the stringtmp[num] = strtok(p," ");while(tmp[++num] = strtok(NULL," "));pid = fork();if(pid == 0){if(sigprocmask(SIG_UNBLOCK,set,NULL) == -1){printf("sigset error~!\n");exit(0);}//execute itint error = execvp(tmp[0],tmp);if(error < 0){printf("Command not found~!\n");//exit(0);}free(tmp);exit(0);}elsewait(NULL);}//command contains '>'void redi(char *p){char * str = strtok(p,"+");char * file_name = strtok(NULL," ");char **tmp = (char **)malloc(SUBLENGTH*sizeof(char*)); int num = 0;int file,file_old,file_new;pid_t pid;tmp[num] = strtok(str," ");while(tmp[++num] = strtok(NULL," "));// open the filefile = open(file_name,O_WRONLY | O_CREAT);if(file == -1){printf("open file error!\n");free(tmp);}// inorder to recoverfile_old = dup(STDOUT_FILENO);// redirect the streamfile_new = dup2(file,STDOUT_FILENO);if(file_new == -1){printf("dup error~!\n");close(file);return ;}pid = fork();if(pid == 0){int error = execvp(tmp[0],tmp);if(error < 0){printf("Command is not found~!\n");exit(0);}close(file);free(tmp);exit(0);}else{wait(NULL);//recover the streamif(dup2(file_old,file_new)== -1){printf("dup2 error\n");}}}//command contains '|'void piped(char *p){char *str1 = strtok(p,"+");char *str2 = strtok(NULL,"+");char line[LINELENGTH];// use pipe implements the '|'FILE *in = popen(str1,"r");FILE *out = popen(str2,"w");if(in == NULL||out == NULL){printf("popen error~!\n");return ;//read the string and write to outwhile(fgets(line,LINELENGTH,in) != NULL)if(fputs(line,out) == EOF)printf("fputs error~!\n");pclose(in);pclose(out);}// implements background taskvoid bgtask(char *p){char *str = strtok(p,"+");char **tmp = (char **)malloc(SUBLENGTH*sizeof(char *)); int num = 0;pid_t pid;//splittmp[num] = strtok(str," ");while(tmp[++num] = strtok(NULL," "));if((pid = fork())< 0 ){printf("fork error~!\n");return ;if(pid == 0){if(fork())exit(0); //parent diedelse{int error = execvp(tmp[0],tmp);if(error < 0){printf("commamd not found");exit(0);}exit(0);}}}。