该实验主要自己实现一个简易的shell,有一些难度,而且有些错误很难找,做完后感觉对shell有了更好的理解。
该实验在tsh.c
文件中实现了大部分的框架,需要自己完成以下函数内容:
quit
、fg
、bg
和job
,大约25行。SIGCHLD
信号的处理函数`SIGINT
信号的处理函数sigtstp_handler:
SIGTSTP信号的处理函数我们希望实现的shell具有以下功能:
tsh>
|
或I/O重定向<
和>
ctrl-c
(ctrl-z
)应该会导致SIGINT
(SIGTSTP
)信号发送到当前前台作业以及该作业的任何后代,如果没有前台作业,那么信号应该没有效果。&
结束,则shell应该在后台运行作业,否则它将在前台运行该作业。quit
、jobs
、bg <job>
和fg <job>
。quit: 退出当前shell
jobs: 列出所有后台运行的工作
bg <job>: 这个命令将会向<job>代表的工作发送SIGCONT信号并放在后台运行,<job>可以是一个PID也可以是一个JID。
fg <job>: 这个命令会向<job>代表的工作发送SIGCONT信号并放在前台运行,<job>可以是一个PID也可以是一个JID。
通过make
来得到我们shell的可执行目标文件,然后这里给出了一系列的验证文件,比如trace01.txt
,其中包含了一些命令,我们可以通过make test01
来得到我们shell的输出结果,可以和make rtest01
输出的结果对比,或tshref.out
比较,判断我们shell是否正确。
eval
execve
fork
fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
把tsh编译出来就能过
要求添加内置命令quit
也是要求添加内置命令quit
添加后台运行的功能,直接用CSAPP书上的代码,但是会有内存泄露的问题
除了实现后台运行的功能,还需要实现内置命令jobs,思路与书中642页程序大致相同
运行了一个./myspin 4
并在两秒后对其中断,键盘按下ctrl-c后,进入信号处理函数,然后终止前台正在运行的函数。在处理函数中,需要获取前台正在运行进程的pid,而访问全局变量时最好对信号量进行阻塞。
对前面两个trace的组合
这一条测试是对前台程序进行停止(挂起),即对sigtstp_handler
函数进行编写。该函数与sigint_handler
几乎一模一样,只是在kill
中的参数不同而已。
trace09是对bg
和fg
指令进行解析并运行。因此,这里需要完成do_fg
函数。该函数需要做到以下几点:
bg
和 fg
命令进行区分该函数的大致思路是这样的
fg/bg %num
指令进行操作时,是无法获取当前指令的pid的,因此更改运行状态等会遇到一些小麻烦,解决的一种方法是自己写一个jid2pid
以及更改对应status
的函数,这里我嫌麻烦直接就获取job的指针直接修改了)status
分别进行操作(fg
的实质就是激活后台进程在前台等待,bg
只是简单的重启进程即可)这里遇到了执行fg %1
后程序会卡住的问题,上网一查找到了答案
如果能过顺利完成前10个测试条例,其余的都是对之前的一些组合,基本都能通过测试。
tsh.c代码:
https://github.com/A2kaid/CSAPP-Study-Note/blob/main/ShellLab/tsh.c
运行结果:
全部评论 (暂无评论)
info 还没有任何评论,你来说两句呐!