mybash的实现
2018-2019-1 20165226《信息安全系统设计基础》 bash的实现
目录
一、学习fork,exec,wait
**** ## 1、fork - 格式 ``` //头文件 #include返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1函数说明:一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。
- 举例
#include <stdio.h>
#include <unistd.h>
void main()
{
int i;
printf("hello, %d\n",getpid());
i=2;
fork();
printf("var %d in %d\n", i, getpid());
}
结果:
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就可以了
3、wait
- 函数原型
#include<sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status)
参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程, wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。
二、实现bash
**** - 伪代码while(1)
{
fgets(命令行输入);
if(内置的shell命令)
{
解释命令;
}
else if(可执行文件)
{
新的子进程加载并运行文件;
}
}
- 代码
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#define MAX 128
void 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;
}
- 测试代码
ls
ls -a
git --version
- 结果
返回目录![]