实现mybash
任务内容
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.写出伪代码,产品代码和测试代码
伪代码
#include<stdio.h>
int main(){
读取命令行输入内容;
判断是否为bash中的命令;
判断是否新建子进程并执行;
执行命令结束;
}
mybash.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/wait.h>
#include<string.h>
int main()
{
while(1)
{
printf("20165336mybash:");
fflush(stdout);
char buffer[1024];
int read_size = read(1, buffer, sizeof(buffer));
if (read_size > 0)
{
buffer[read_size - 1] = 0;
}
char* bash_argv[32] = {NULL};
int bash_index = 0;
char* start = buffer;
while (*start != '\0')
{
while (*start != '\0' && isspace(*start))
{
*start = '\0';
start++;
}
bash_argv[bash_index++] = start;
while (*start != '\0' && !isspace(*start))
{
start++;
}
}
pid_t pid = vfork();
if (pid < 0)
{
printf("vfork failure\n");
exit(1);
}
else if (pid == 0)
{
int i = 0;
int flag = 0;
for (; bash_argv[i] != NULL; ++i )
{
if (strcmp(">", bash_argv[i]) == 0)
{
flag = 1;
break;
}
}
int copyFd;
bash_argv[i] = NULL;
if (flag)
{
if (bash_argv[i+1] == NULL)
{
printf("command error\n");
exit(1);
}
close(1);
int fd = open(bash_argv[i+1], O_WRONLY | O_CREAT, 0777);
copyFd = dup2(1, fd);
}
execvp(bash_argv[0], bash_argv);
if (flag)
{
close(1);
dup2(copyFd, 1);
}
exit(1);
}
else
{
int status = 0;
int ret = waitpid(pid, &status, 0);
if (ret == pid)
{
if (WIFEXITED(status))
{
printf("exitCode is %d\n", WEXITSTATUS(status));
}
else if (WIFSIGNALED(status))
{
printf("signal is %d\n", WTERMSIG(status));
}
}
}
}
return 0;
}
(包含代码托管链接)
3.发表知识理解,实现过程和问题解决的博客### 遇到的问题在实现bash后输入命令ls 出现问题当加入/bin/ls后方能显示当前文件夹下的内容查找资料有的说是环境变量的设置问题,未能找到很好的答案,继续探索中。

实现mybash的更多相关文章
- Mybash的实现
Mybash的实现 要求: 使用fork,exec,wait实现mybash 写出伪代码,产品代码和测试代码 发表知识理解,实现过程和问题解决的博客(包含代码托管链接) 背景知识 1. fork 使用 ...
- 2017-2018-1 20155215 第五周 mybash的实现
题目要求 使用fork,exec,wait实现mybash 写出伪代码,产品代码和测试代码 发表知识理解,实现过程和问题解决的博客(包含代码托管链接) 学习fork,exec,wait fork ma ...
- 2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现
2017-2018-1 20155306 <信息安全系统设计基础>Mybash的实现 要求: 使用fork,exec,wait实现mybash 写出伪代码,产品代码和测试代码 发表知识理解 ...
- 20165223 《信息安全系统设计基础》 实现mybash
一.了解 mybash 1. 简介 bash 是 Bourne Again Shell 的缩写,是linux默认的标准shell(也是大家常说的系统内核),bash也是Unix/Linux上常见的 ...
- 20165220 mybash
使用fork,exec,wait实现mybash - 写出伪代码,产品代码和测试代码 - 发表知识理解,实现过程和问题解决的博客(包含代码托管链接) 1.fork 功能:创建一个新的进程 一个现存进程 ...
- 实现mypwd和mybash
一.pwd 1.学习pwd命令 man pwd查看pwd功能 可以得知pwd功能是打印当前目录 2.研究pwd实现需要的系统调用(man -k; grep),写出伪代码 (1)man -k direc ...
- 实现mypwd&mybash&myod&读者写者
目录: 一.mypwd 二.mybash 三.myod 四.读者.写者 一.实现mypwd 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 实现mypwd 测试m ...
- 20155219 mybash的实现
第五周加分题--mybash的实现 题目要求 1.使用fork,exec,wait实现mybash 2.写出伪代码,产品代码和测试代码 3.发表知识理解,实现过程和问题解决的博客(包含代码托管链接) ...
- 20155326 第五周加分题--mybash的实现
第五周加分题--mybash的实现 题目要求 1.使用fork,exec,wait实现mybash 2.写出伪代码,产品代码和测试代码 3.发表知识理解,实现过程和问题解决的博客(包含代码托管链接) ...
随机推荐
- Python的数据库mongoDB的入门操作
Python代码: import pymongo # 获取本地端口,激活mongo客户端 client = pymongo.MongoClient('localhost',27017) # 创建一个数 ...
- C#中IEnumerable、ICollection、IList、List之间的区别
IEnumerable.ICollection.IList.List之间的区别,本文分别分析了它的实现源码,从而总结出了它们之间的关系和不同之处. 首先我看看 IEnumerable: // 摘要: ...
- Django 复习
Django 基础1 day49 老师的博客:https://www.cnblogs.com/yuanchenqi/articles/6083427.html http://www.cnblogs.c ...
- Mybatis 级联查询时只查出了一条数据
造成这个问题的原因是: 主表和明细表的id字段名相同造成的. 问题的关键在于resultMap中如果不定义类似主键之类的能够区分每一条结果集的字段的话,会引起后面一条数据覆盖前面一条数据的现象.
- kubernetes 学习资料
谷歌大神详解 Kubernetes 配置管理最佳方法 https://www.kubernetes.org.cn/3031.html all in on kubernetes https://gith ...
- jqweui 关于$(document.body).infinite的bug
jqweui,0.8.2版本infinite存在bug,会存在下拉不触发的情况,解决办法: 源代码3730行附近 Infinite.prototype.scroll = function() { va ...
- "title_activity_dist" is not translated in "zh-rCN" (Chinese: China)
根据报错提示,是说我没有对string文件做国际化翻译操作,但是我报错的项目并没有做国际化,所以并没有values-zh-rCN和values-zh-rTW两个文件夹,最后我发现原来是当前项目引用的一 ...
- 使用git创建与合并分支
一.概述 学会使用git命令对项目进行创建分支,并在创建结束后合并到主分支上. 问:为什么要创建分支? 答:在原来的分支上创建一个自己的分支进行开发,在开发完毕后一次性合并到原先的分支,这样既保证安全 ...
- Matrix 高斯消元Gaussian elimination 中的complete pivoting和partial pivoting
首先科普下Pivoting的含义 一般翻译为“主元”,在对矩阵做某种算法时,首先进行的部分元素.在线性规划的单纯形法中常见.wiki的解释如下:Pivot element(the first elem ...
- webpack模块化原理
https://segmentfault.com/a/1190000010349749 webpack模块化原理-commonjs https://segmentfault.com/a/119 ...