简易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);
}

 

posted @ 2022-07-13 21:12  *^VV^*  阅读(52)  评论(0编辑  收藏  举报