2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现

2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现


要求:

  • 使用fork,exec,wait实现mybash
  • 写出伪代码,产品代码和测试代码
  • 发表知识理解,实现过程和问题解决的博客(包含代码托管链接)

知识基础:

1.shell

  • shell命令分为 内建命令 & 外部命令

  • 内建命令(builtin command) 是shell解释程序内建的,由shell直接执行,不需要派生新的进程。

  • 外部命令分为两种: 二进制代码 或 shell脚本。shell执行外部命令时,会创建一个新的进程来执行命令。默认shell将等待直到该进程结束。

    常见的外部命令:

grep more cat mkdir rmdir ls  sort  ftp  telnet  ssh   ps `

2.fork()

  • fork()用来创建一个子进程,该子进程是执行该函数的父进程的一个复制的映像.
  • 注意:fork()函数有一个特点是一次调用返回两个值;

    如果返回值为0,则是子进程;如果返回值大于0,则是父进程(此时返回值就是子进程的PID);(如果返回值为-1,则创建子进程失败).

    1.用曼命令查找系统内可调用的具有创建新进程的函数:

    2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现

2.用man fork 查看函数要用的头文件以及其他用法:

2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现

3.编写代码验证函数基本功能:


pid = fork();
if (pid < 0) {
perror("fork failed");
exit(1);
}
else{
if(fork==0)
printf(" ID childs: %d\n", getpid());
else
printf(" ID parent : %d\n", getpid() );
}

2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现

3.exec()

  • 当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。
  • 注意:exec函数只有出错的返回值而没有成功的返回值。
  1. 用 man -k execute|grep 3查看C中用于执行进程的函数,有哪些:

    2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现

  2. 用man命令查看这些函数有什么不同:在[exec函数用法总结]中有非常详细的介绍(http://blog.csdn.net/zjwson/article/details/53337212)

    2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现

    3.验证exce()的功能:

    char *const argv[] ={"hello", NULL};
execv("hello", argv);
printf("123456789\n");
return 0;
//调用之后,不再显示printf中的内容,直接执行“hello”。

2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现

4.wait()

  • wait系统调用会使父进程暂停执行,直到它的等待的子进程结束为止。也就是说wait是阻塞的。
  • wait可以返回两个信息,直接返回子进程的PID,还有status(注意这个值不是在子进程中调用exit函数中的退出码,下面有专门的宏使用该status)。用man命令查看其头文件和用法,用代码验证如下:

    2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现
pr=wait(NULL);

printf("child ID : %d \n",pr);
//wait成功后,接收到子进程的ID

2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现

5.Mybash()

代码托管

2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现

伪代码:

1.定义命令数组,读入用户输入的指令;
2.定义一个结束条件,满足条件结束;否则调用wait()保证在未输入结束命令前,一直提示输入commond;
3.调用fork函数生成一个子进程;
4.判断fork返回值pid是否为零,如果为零调用execlp函数;如果不为零,结束;

产品代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <wait.h>
#include <string.h> int main() {
char commond[50];//定义命令数组
int pid;
int ret;
while (1) {//保证循环不断输入命令
printf("commond:");
scanf("%s", commond);
if (strcmp(commond, "exit") == 0)//结束标志
exit(0);
else {
pid = fork();
if (pid == -1) {//创建进程失败,退出
printf("error ocurred!");
exit(0);
} else if (pid == 0) {//创建成功,读入命令并执行
ret= execlp(commond, commond, NULL);
if (ret == -1) {//执行失败返回-1,退出,成功没有返回值
exit(0);
}
} else {
wait(NULL);//等待子程序终止,防止子程序成为僵尸程序
}
} }
return 0;
}

2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现

参考资料

linux进程控制函数--fork,exec,exit,wait,sleep

进程控制

上一篇:Elasticsearch5.5安装部署


下一篇:activity 与 service 之间的通信