简易mysh实现(fork exec wait)
简易mysh示例:mysh.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <glob.h>
#include <string.h>
#define DELIM " \t\n"
struct cmd_st //自定义结构体
{
glob_t globRes;
};
static void prompt(void) //打印显示函数
{
printf("mysh v0.1$ ");
}
static void parse(char *str,struct cmd_st *cmd) //字符串解析
{
char *res;
int i=0;
while(1) //循环解析
{
res = strsep(&str,DELIM); //字符串拆分(通过DELIM)
if(res == NULL) //空字符串表示到末尾退出
break;
else if(res[0] == '\0') //字符串首字母为‘\0’表示遇到多个拆分符。
continue;
glob(res,GLOB_NOCHECK|GLOB_APPEND*i,NULL,&cmd->globRes); //将拆分的字符串存入globRes结构体内。(第一次不能加GLOB_APPEND否者将子保存一个)
i = 1;
}
}
int main()
{
char *getstring=NULL;
size_t getlenth=0;
ssize_t ret;
struct cmd_st cmd;
pid_t pid;
while(1)
{
prompt(); //打印提示信息
ret = getline(&getstring,&getlenth,stdin); //从标准输入读取一行数据 (必须将前两个参数初始化否者出错)
if(ret <0)
{
perror("getline()");
exit(1);
}
parse(getstring,&cmd); //解析数据并存入cmd结构体中
if(0) //内部命令暂时不能解析执行
{
}
else //外部命令执行
{
pid = fork(); //创建子进程
if(pid <0)
{
perror("fork()");
exit(1);
}
else if(pid ==0) //子进程处理
{
ret = execvp(cmd.globRes.gl_pathv[0],cmd.globRes.gl_pathv); //通过execvp替换生成的子进程执行外部命令。
if(ret <0)
{
perror("execvp()");
exit(1);
}
}
}
wait(NULL); //等待子进程执行完毕并回收资源。
}
exit(0);
}