当前位置: 首页 > news >正文

网站做app的软件有哪些莱芜二手房产网

网站做app的软件有哪些,莱芜二手房产网,网站建设东莞公司,六安头条网编写自己的shell 进程程序替换 替换原理 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数 以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动 例程开始执行…

编写自己的shell

进程程序替换

替换原理

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数
以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动
例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。

在这里插入图片描述

替换函数

其实有几种以exec开头的函数,统称exec函数:

#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);

解释
exec是函数替换的开头,后面跟的都是多加的功能:
l:list的简写,表示参数采用列表。
p:path的简写,就是自动搜索并添加环境变量。可以使用环境变量PATH,无需写全路径。
v:vector的简写,是可以用参数数组。
e:environment的简写,就是环境变量。就是带e都要自己组装环境变量,而且是数组形式传入。

这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
如果调用出错则返回-1
所以exec函数只有出错的返回值而没有成功的返回值。

在这里插入图片描述
可变参数
我们刚刚可以看到int execl(const char *path, const char *arg, …);
比如:

int func(int, ... )  {...
}int main() {func(2, 2, 3);func(3, 2, 3, 4);
}

函数 func() 最后一个参数写成省略号,即三个点号(…),省略号之前的那个参数是 int,代表了要传递的可变参数的总数。为了使用这个功能,您需要使用 stdarg.h 头文件,该文件提供了实现可变参数功能的函数和宏。具体步骤如下:
定义一个函数,最后一个参数为省略号,省略号前面可以设置自定义参数。
在函数定义中创建一个 va_list 类型变量,该类型是在 stdarg.h 头文件中定义的。
使用 int 参数和 va_start() 宏来初始化 va_list 变量为一个参数列表。宏 va_start() 是在 stdarg.h 头文件中定义的。
使用 va_arg() 宏和 va_list 变量来访问参数列表中的每个项。
使用宏 va_end() 来清理赋予 va_list 变量的内存。

也就是说可变参数是放在传入参数最后,放在中间必须在输入结束之后再输入一个NULL,而且可变参数和前面放的参数类型一致。
exec调用举例:

#include <unistd.h>
int main()
{
char *const argv[] = {"ps", "-ef", NULL};
char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};
execl("/bin/ps", "ps", "-ef", NULL);
// 带p的,可以使用环境变量PATH,无需写全路径
execlp("ps", "ps", "-ef", NULL);
// 带e的,需要自己组装环境变量
execle("ps", "ps", "-ef", NULL, envp);
execv("/bin/ps", argv);
// 带p的,可以使用环境变量PATH,无需写全路径
execvp("ps", argv);
// 带e的,需要自己组装环境变量
execve("/bin/ps", argv, envp);
exit(0);
}

事实上,只有execve是真正的系统调用,其它五个函数最终都调用 execve,所以execve在man手册 第2节,其它函数在
man手册第3节。这些函数之间的关系如下图所示。

在这里插入图片描述

开始写自己的shell

用下图的时间轴来表示事件的发生次序。其中时间从左向右。shell由标识为sh的方块代表,它随着时间的流逝从左
向右移动。shell从用户读入字符串"ls"。shell建立一个新的进程,然后在那个进程中运行ls程序并等待那个进程结
束。在这里插入图片描述
每当输入一个命令时,bash就会创建一个子进程来实现的要的命令进程,上述就是ls,等待子进程退出,主进程继续等待命令输入和读取命令,再创建子进程等…

第一步创建一个界面然后让他一直死循环

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include  <ctype.h>#define MAX_CMD 1024
char command[MAX_CMD];
int myshell_face()
{memset(command, 0x00, MAX_CMD);printf("[Tomshell$]#");fflush(stdout);if (scanf("%[^\n]%*c", command) == 0){getchar();return -1;}return 0;
}
int main(int argc, char *argv[])
{while (1) // shell主循环{myshell_face()}return 0;
}

当然这个界面是可以输入命令的,但是你怎么输入都没用。

接下来是解析你输入的命令了。
把刚刚输入的命令行分析出来,比如遇到空格就会再次push_back命令行数组,当有空格就跳过空格,知道遇到NULL为止。

char **do_parse(char *command)
{int argc = 0;static char *argv[32];char *ptr = command;while (*ptr != '\0'){if (!isspace(*ptr))//如果不是空格就一直读取命令,直到遇到空格{argv[argc++] = ptr;while ((!isspace(*ptr)) && (*ptr) != '\0')//#include  <ctype.h>   isspace检测是否遇到空格{ptr++;              //如果不是空格就一直读取命令,直到遇到空格}}else{while (isspace(*ptr))//如果命令前几个是空格就消除空格{//*ptr = '\0';//这句就不用加了ptr++;}}}argv[argc] = NULL;return argv;
}

解析完之后返回的是命令行参数数组指针

开始创建子进程并且用execvp替换子进程。

int do_exec(char *command)//进程替换函数=》用的就是exec
{char **argv = {NULL};int pid = fork(); // 一切形式的进程都让子进程去办,子进程就是白手套。if (pid == 0){argv = do_parse(command);if (argv[0] == NULL){exit(-1);}execvp(argv[0], argv); // 进程替换函数,可以添加环境变量p(path),参数格式是数组v(vector)}                          // 可以把exec当作call(goto)函数,exit当作return函数。else{waitpid(pid, NULL, 0);}return 0;
}

这样就可以在子进程实现命令行进程了。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include  <ctype.h>#define MAX_CMD 1024
char command[MAX_CMD];
int myshell_face()
{memset(command, 0x00, MAX_CMD);printf("[Tomshell$]#");fflush(stdout);if (scanf("%[^\n]%*c", command) == 0){getchar();return -1;}return 0;
}
char **do_parse(char *command)
{int argc = 0;static char *argv[32];char *ptr = command;while (*ptr != '\0'){if (!isspace(*ptr))//如果不是空格就一直读取命令,直到遇到空格{argv[argc++] = ptr;while ((!isspace(*ptr)) && (*ptr) != '\0')//#include  <ctype.h>   isspace检测是否遇到空格{ptr++;              //如果不是空格就一直读取命令,直到遇到空格}}else{while (isspace(*ptr))//如果命令前几个是空格就消除空格{//*ptr = '\0';//这句就不用加了ptr++;}}}argv[argc] = NULL;return argv;
}
int do_exec(char *command)//进程替换函数=》用的就是exec
{char **argv = {NULL};int pid = fork(); // 一切形式的进程都让子进程去办,子进程就是白手套。if (pid == 0){argv = do_parse(command);if (argv[0] == NULL){exit(-1);}execvp(argv[0], argv); // 进程替换函数,可以添加环境变量p(path),参数格式是数组v(vector)}                          // 可以把exec当作call(goto)函数,exit当作return函数。else{waitpid(pid, NULL, 0);}return 0;
}
int main(int argc, char *argv[])
{while (1) // shell主循环{if (myshell_face() < 0)continue;do_exec(command);}return 0;
}

最终成果:
在这里插入图片描述

http://www.yayakq.cn/news/724883/

相关文章:

  • 先做公众号在做网站郑州网站seo技术
  • 微信营销网站(含html源文件)免费下载无锡自助建站软件
  • 阿里云域名 设置网站中英文外贸网站源码
  • 搞笑资讯网站源码音乐网站设计外国
  • wordpress地址不能修改密码长沙搜索排名优化公司
  • 电信200m宽带做网站卡吗静态网页制作实验报告
  • 寻找网络公司做公司网站升级改版简述网站开发流程 旅游
  • 湖南张家界网站建设seo优化是啥
  • 产品通过网站做营销企业网站案例欣赏
  • wap网站有哪些做公众号的网站有哪些功能
  • 上海网站建设服务电话门户网站建设培训简报
  • 如何安装网站模板企业合同管理系统
  • 一级a做爰片2202网站汕头市建设网
  • 深圳网站和app建设湖南的商城网站建设
  • 网站制作西安企业网站制作网站背景图片优化
  • 网站建设学什么语音跨境电商app下载
  • 网站开发及后期维护东莞南城网站建设公司怎么样
  • 城乡住房规划建设局网站网站开发流程有哪几个阶段
  • 上海大型网站制作公司装饰设计的变形手法有哪些
  • 网站的制作与调试南阳企业做网站
  • dedecms5.7环保科技公司网站模板做app模板下载网站
  • 宜宾建设机械网站wordpress企业官网插件
  • 网站 费用专做杰伦头像的网站
  • 写作网站可保存做网站视频学什么专业
  • 红网常德论坛sem优化师
  • 网站建设毕业设计报告书北京室内设计公司排行榜
  • 网站关键词优化软件网站建设发布实训总结
  • 网站建设一条龙wordpress 不做SEO
  • 霍山做网站wordpress 入侵视频
  • 整站优化与关键词排名网盘手机app官网下载