博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mybash的实现
阅读量:6229 次
发布时间:2019-06-21

本文共 2480 字,大约阅读时间需要 8 分钟。

2018-2019-1 20165226《信息安全系统设计基础》 bash的实现

目录


一、学习fork,exec,wait


1、fork

  • 格式
//头文件#include 
//函数定义pid_t fork( void );

1047870-20181125180650571-33288388.png

返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1函数说明:一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。

  • 举例
#include 
#include
void main(){ int i; printf("hello, %d\n",getpid()); i=2; fork(); printf("var %d in %d\n", i, getpid());}

结果:

1047870-20181125170104092-2115990627.png

2、exec

  • exec家族

    只有)int execve(const char *path, char *const argv[], char *const envp[]);是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。

  • 书写格式:

    先定义一个指针数组:char *argv[]={“ls”,”-l”,(char *)0}

    用execv调用ls:execv(“/bin/ls”,argv)
    如果用execvp
    execvp(“ls”,argv) //直接写ls就可以了

    1047870-20181125180756411-82270313.png

3、wait

  • 函数原型
#include
#include
pid_t wait(int *status)

参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程, wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。

1047870-20181125180822816-1097974531.png

二、实现bash


  • 伪代码
while(1){    fgets(命令行输入);    if(内置的shell命令)    {        解释命令;    }    else if(可执行文件)    {        新的子进程加载并运行文件;    }}
  • 代码
#include 
#include
#include
#include
#include
#include
#define MAX 128void eval(char *cmdline);int parseline(char *buf, char **argv);int builtin_command(char **argv);int main(){ char cmdline[MAX]; printf("This is 20165226's bash!\n"); while(1) { printf("> "); fgets(cmdline, MAX, stdin); if(feof(stdin)) exit(0); eval(cmdline); }}void eval(char *cmdline){ char *argv[MAX]; char buf[MAX]; int bg; pid_t pid; strcpy(buf,cmdline); bg = parseline(buf,argv); if(argv[0]==NULL) return; if(!builtin_command(argv)) { if((pid=fork()) == 0) { if(execvp(argv[0],argv) < 0) { printf("%s : Command not found.\n",argv[0]); exit(0); } } } if(!bg) { int status; if(waitpid(-1,&status,0) < 0) printf("waitfg: waitpid error!"); } else { printf("%d %s",pid, cmdline); return; }}int builtin_command(char **argv){ if(!strcmp(argv[0], "quit")) exit(0); if(!strcmp(argv[0],"&")) return 1; return 0;}int parseline(char *buf,char **argv){ char *delim; int argc; int bg; buf[strlen(buf)-1]=' '; while(*buf && (*buf == ' ')) buf++; argc=0; while( (delim = strchr(buf,' '))) { argv[argc++] = buf; *delim= '\0'; buf = delim + 1; while(*buf && (*buf == ' ')) buf++; } argv[argc] = NULL; if(argc == 0) return 1; if((bg=(*argv[argc-1] == '&')) != 0) argv[--argc] = NULL; return bg;}
  • 测试代码
lsls -agit --version
  • 结果
    1047870-20181125174617763-156157835.png

[]

转载于:https://www.cnblogs.com/musea/p/10016466.html

你可能感兴趣的文章
嵌入式系统基础及知识及接口技术总结
查看>>
指针和数组都是C语言的精髓所在,两者有何联系区别?
查看>>
Homebrew简介和基本使用
查看>>
如何将DWG批量转成高清晰JPG图片
查看>>
以太坊web3.js文档翻译及说明
查看>>
list集合练习笔记
查看>>
SqlServer2008 R2数据库主从搭建
查看>>
一个程序猿试用有道云笔记VIP功能体验
查看>>
简单对接快递100
查看>>
Etherscan以太坊API官方文档中文版
查看>>
wamp 无法打开localhost:The requested URL / was not...
查看>>
ERC827以太坊通证标准
查看>>
PropertyPlaceholderConfigurer ---Spring管理配置文件
查看>>
初学Python:写码时应该缩进使用 tab 还是空格?
查看>>
10.15 iptables filter表案例, iptables nat表应用
查看>>
java B2B2C Springboot电子商城系统-路由网关(zuul)
查看>>
重磅课程|《CNCF x Alibaba 云原生技术公开课》正式开讲!
查看>>
java反射+注解实现Entity类与Dto类相互转换
查看>>
LVM讲解和磁盘故障小案例
查看>>
年后跳槽怕面试不过关?搞懂并发编程,轻松应对80%的面试场景
查看>>