zoukankan      html  css  js  c++  java
  • xv6-----shell

    这是操作系统原理课程的第一个编程作业,补全shell的功能。

    主要实现了基础的三类命令

    • 可执行的程序命令
    • 重定向命令
    • 管道命令

    实现的"基类" (原谅我用了这个词)就是struct cmd这个结构体就一个成员,用于记录命令的类型.

    三类, ' ' 表示可执行程序 '|' 表示管道命令,  '<'  和'>' 表示重定向类型.

    每一个类型分别继承基类,派生出对应的三类结构体 

    struct execcmd

    struct redircmd

    struct pipecmd

    void runcmd(struct cmd * cmd);

    这个函数是真正驱动调用实现shell的核心.负责调用系统接口函数 execv(), open(), close(), dup(), pipe()等等一系列函数,来完成我们既定的目标.

    作业也就是补全这个函数.

    这是个递归的函数!

    下面是来自github上的代码,仅摘录runcmd函数

     1 void
     2 runcmd(struct cmd *cmd)
     3 {
     4   int p[2]; // used for pipe line in shell
     5   int r;    // return value
     6   struct execcmd *ecmd;
     7   struct pipecmd *pcmd;
     8   struct redircmd *rcmd;
     9 
    10   if(cmd == 0)
    11     exit(0);
    12   
    13   switch(cmd->type){
    14   default:
    15     fprintf(stderr, "unknown runcmd
    ");
    16     exit(-1);
    17 
    18   case ' ':
    19     ecmd = (struct execcmd*)cmd;
    20     if(ecmd->argv[0] == 0)
    21       exit(0);
    22     //fprintf(stderr, "exec not implemented
    ");
    23     // Your code here ...
    24     if (access(ecmd->argv[0], S_IXUSR | S_IRUSR) == 0)
    25     {
    26         execv(ecmd->argv[0], ecmd->argv);
    27     }
    28     else
    29     {
    30         if(chdir("/bin/") < 0)
    31         {
    32             printf("change directory failed in line %d
    ", __LINE__);
    33             exit(0);
    34         }
    35         execv(ecmd->argv[0], ecmd->argv);
    36     }
    37     fprintf(stderr, "execv() %s failed in line %d
    ", ecmd->argv[0], __LINE__);
    38     break;
    39 
    40   case '>':
    41   case '<':
    42     rcmd = (struct redircmd*)cmd;
    43     //fprintf(stderr, "redir not implemented
    ");
    44     // Your code here ...
    45     close(rcmd->fd);
    46     if(open(rcmd->file, rcmd->mode) < 0)
    47     {
    48         fprintf(stderr, "Try to open :%s failed
    ", rcmd->file);
    49         exit(0);
    50     }
    51     runcmd(rcmd->cmd);
    52     break;
    53 
    54   case '|':
    55     pcmd = (struct pipecmd*)cmd;
    56     //fprintf(stderr, "pipe not implemented
    ");
    57     // Your code here ...
    58     if(pipe(p) < 0)
    59     {
    60         fprintf(stderr, "call syscall pipe() failed in line %d
    ", __LINE__);
    61         exit(0);
    62     }
    63 
    64     if(fork1() == 0)
    65     {
    66         close(1);
    67         dup(p[1]);
    68         close(p[0]);
    69         close(p[1]);
    70         runcmd(pcmd->left);
    71     }
    72 
    73     if(fork1() == 0)
    74     {
    75         close(0);
    76         dup(p[0]);
    77         close(p[0]);
    78         close(p[1]);
    79         runcmd(pcmd->right);
    80     }
    81 
    82     close(p[0]);
    83     close(p[1]);
    84     wait();
    85     wait();
    86     break;
    87   }    
    88 
    89   exit(0);
    90 }

    有兴趣可以点击查看详情

  • 相关阅读:
    Response.AddHeader
    动态生成Excel到客户端
    java多线程编程核心技术
    Centos7安装mysql8(tar)
    linux下载安装tomcat+jdk
    cmd中传递参数运行java程序
    Java(静态)变量和(静态)代码块的执行顺序
    web(war)工程引用另一个web工程(jar包)
    转换一个字段中含有多个另外一张表的id | | 行转列
    hdu2046骨牌铺方格
  • 原文地址:https://www.cnblogs.com/tjulym/p/4973496.html
Copyright © 2011-2022 走看看