任务内容

1.使用fork,exec,wait实现mybash

查找资料:

fork函数

通过fork()系统调用我们可以创建一个和当前进程印象一样的新进程.我们通常将新进程称为子进程,而当前进程称为父进程.而子进程继承了父进程的整个地址空间,其中包括了进程上下文,堆栈地址,内存信息进程控制块(PCB)等.通过man手册我们可以轻松知道fork()包含的头文件<sys/types.h>和<unistd.h>,功能就是创建一个子进程.函数原型:pid_t fork(void),pid_t是带一个代表经常号pid的数据结构.如果创建成功一个子进程,对于父进程来说是返回子进程的ID.而对于子进程来说就是返回0.而返回-1代表创建子进程失败.

exec函数

在fork后的子进程中使用exec函数族,可以装入和运行其它程序(子进程替换原有进程,和父进程做不同的事)。exec函数族可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段。在执行完后,原调用进程的内容除了进程号外,其它全部被新程序的内容替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行脚本文件。

wait函数

int wait(int* statloc);

int waitpid(pid_t pid, int* statloc, int options);

这两个函数的区别如下:1. 在一个子进程终止前,wait使其调用者阻塞,而waitpid有一个选项,可使调用者不阻塞;2. waitpid()并不等待在其调用之后的第一个终止的子进程,它有若干个选项,可以控制它所等待的进程;



2.写出伪代码,产品代码和测试代码

伪代码

  1. #include<stdio.h>
  2. int main(){
  3. 读取命令行输入内容;
  4. 判断是否为bash中的命令;
  5. 判断是否新建子进程并执行;
  6. 执行命令结束;
  7. }

mybash.c

  1. #include<stdio.h>
  2. #include<unistd.h>
  3. #include<stdlib.h>
  4. #include<sys/types.h>
  5. #include<sys/stat.h>
  6. #include<sys/wait.h>
  7. #include<string.h>
  8. int main()
  9. {
  10. while(1)
  11. {
  12. printf("20165336mybash:");
  13. fflush(stdout);
  14. char buffer[1024];
  15. int read_size = read(1, buffer, sizeof(buffer));
  16. if (read_size > 0)
  17. {
  18. buffer[read_size - 1] = 0;
  19. }
  20. char* bash_argv[32] = {NULL};
  21. int bash_index = 0;
  22. char* start = buffer;
  23. while (*start != '\0')
  24. {
  25. while (*start != '\0' && isspace(*start))
  26. {
  27. *start = '\0';
  28. start++;
  29. }
  30. bash_argv[bash_index++] = start;
  31. while (*start != '\0' && !isspace(*start))
  32. {
  33. start++;
  34. }
  35. }
  36. pid_t pid = vfork();
  37. if (pid < 0)
  38. {
  39. printf("vfork failure\n");
  40. exit(1);
  41. }
  42. else if (pid == 0)
  43. {
  44. int i = 0;
  45. int flag = 0;
  46. for (; bash_argv[i] != NULL; ++i )
  47. {
  48. if (strcmp(">", bash_argv[i]) == 0)
  49. {
  50. flag = 1;
  51. break;
  52. }
  53. }
  54. int copyFd;
  55. bash_argv[i] = NULL;
  56. if (flag)
  57. {
  58. if (bash_argv[i+1] == NULL)
  59. {
  60. printf("command error\n");
  61. exit(1);
  62. }
  63. close(1);
  64. int fd = open(bash_argv[i+1], O_WRONLY | O_CREAT, 0777);
  65. copyFd = dup2(1, fd);
  66. }
  67. execvp(bash_argv[0], bash_argv);
  68. if (flag)
  69. {
  70. close(1);
  71. dup2(copyFd, 1);
  72. }
  73. exit(1);
  74. }
  75. else
  76. {
  77. int status = 0;
  78. int ret = waitpid(pid, &status, 0);
  79. if (ret == pid)
  80. {
  81. if (WIFEXITED(status))
  82. {
  83. printf("exitCode is %d\n", WEXITSTATUS(status));
  84. }
  85. else if (WIFSIGNALED(status))
  86. {
  87. printf("signal is %d\n", WTERMSIG(status));
  88. }
  89. }
  90. }
  91. }
  92. return 0;
  93. }

(包含代码托管链接)

代码链接

3.发表知识理解,实现过程和问题解决的博客### 遇到的问题在实现bash后输入命令ls 出现问题当加入/bin/ls后方能显示当前文件夹下的内容查找资料有的说是环境变量的设置问题,未能找到很好的答案,继续探索中。

实现mybash的更多相关文章

  1. Mybash的实现

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

  2. 2017-2018-1 20155215 第五周 mybash的实现

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

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

    2017-2018-1 20155306 <信息安全系统设计基础>Mybash的实现 要求: 使用fork,exec,wait实现mybash 写出伪代码,产品代码和测试代码 发表知识理解 ...

  4. 20165223 《信息安全系统设计基础》 实现mybash

    一.了解 mybash 1. 简介   bash 是 Bourne Again Shell 的缩写,是linux默认的标准shell(也是大家常说的系统内核),bash也是Unix/Linux上常见的 ...

  5. 20165220 mybash

    使用fork,exec,wait实现mybash - 写出伪代码,产品代码和测试代码 - 发表知识理解,实现过程和问题解决的博客(包含代码托管链接) 1.fork 功能:创建一个新的进程 一个现存进程 ...

  6. 实现mypwd和mybash

    一.pwd 1.学习pwd命令 man pwd查看pwd功能 可以得知pwd功能是打印当前目录 2.研究pwd实现需要的系统调用(man -k; grep),写出伪代码 (1)man -k direc ...

  7. 实现mypwd&mybash&myod&读者写者

    目录: 一.mypwd 二.mybash 三.myod 四.读者.写者 一.实现mypwd 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 实现mypwd 测试m ...

  8. 20155219 mybash的实现

    第五周加分题--mybash的实现 题目要求 1.使用fork,exec,wait实现mybash 2.写出伪代码,产品代码和测试代码 3.发表知识理解,实现过程和问题解决的博客(包含代码托管链接) ...

  9. 20155326 第五周加分题--mybash的实现

    第五周加分题--mybash的实现 题目要求 1.使用fork,exec,wait实现mybash 2.写出伪代码,产品代码和测试代码 3.发表知识理解,实现过程和问题解决的博客(包含代码托管链接) ...

随机推荐

  1. mybatis插入一个对象后获取表中自增的主键Id并且传入到插入的的对象中,方便将对象中其他属性赋值给其他以前表主键Id作为非空字段的表

    原本的sql语句为: <insert id="xx" parameterType="com.hrt.partner.model.ShopInsert"&g ...

  2. 【算法】解析IEEE 754 标准

    目录结构: contents structure [-] 浮点数的存储过程 次正规数(Denormalized Number) 零(zero) 非数值(NaN) 无穷大(infinity) 除数为0. ...

  3. react-native init的时候出现问题:npm WARN React-native@0.35.0 requires a peer of react@~15.3.1 but none was

    react-native init的时候出现问题:npm WARN React-native@0.35.0 requires a peer of react@~15.3.1 but none was ...

  4. elasticsearch 一、环境配置

    简介 ElasticSearch是一个开源的分布式搜索引擎,具备高可靠性,支持非常多的企业级搜索用例,是基于Lucene构建的.支持时间时间索引和全文检索.官网:http://www.elastics ...

  5. 微信小程序开发填坑指南V1

    近期用了一星期的时间,开发了一个小程序.小程序名称是:小特Jarvis,取自钢铁侠的管家. 后台采用C#编写,WebAPI接口.其实开发时间并不多,小程序本身提供的API,相比公众号的API来说,已经 ...

  6. MyBatis 配置多数据源

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  7. ocelot配置

    动态配置 { "ReRoutes": [], "Aggregates": [], "GlobalConfiguration": { &quo ...

  8. Centos VMware 克隆后 网络配置

    第一步:生产新的网卡地址,启动系统. 第二步:修改主机名(注:此处根据个人需要,不修改也行,此处我是用于搭建集群,修改主机名做区分) 执行命令:vi /etc/sysconfig/network 修改 ...

  9. python处理文件的换行符

    我们知道在Windows平台下的换行符是\r\n,而在linux下的换行符是\n.现在写一个简单程序来测试python是如何处理这些换行符的. 准备文件data.txt,该文件在Windows平台下编 ...

  10. Windows下JDK多版本切换

    根据需要,我们可以在一台电脑上安装多个不同的JDK版本,在使用的过程中,可能需要进行版本质检的切换.下面简单说明在切换过程中需要注意的问题.(个人本机是部署了1.8和1.7版本的,安装目录均在C:\P ...