xv6-lab(1)--shell

来源:互联网 发布:淘宝魅族mx5屏幕总成 编辑:程序博客网 时间:2024/05/17 01:07

shell

shell 要求完成的功能有三:

  1. 可执行的程序命令
  2. 重定向命令
  3. 管道命令

1. 可执行程序

shell要求可以调用可执行程序, 可以用execv函数来实现

    头文件:#include <unistd.h>    定义函数:int execv (const char * path, char * const argv[]);    函数说明:execv()用来执行参数path 字符串所代表的文件路径, 与execl()不同的地方在于execv()只需两个参数, 第二个参数利用数组指针来传递给执行文件。    返回值:如果执行成功则函数不会返回, 执行失败则直接返回-1, 失败原因存于errno 中。

exec 函数传递的 filename参数按照 PATH 环境变量,在指定的各个目录中寻找可执行文件。

PATH 环境变量包含一张目录表(称为路径前缀),目录之间用冒号(:)分割。例如,
PATH=/bin:/usr/bin:/usr/local/bin:.


为了实现PATH环境变量, 使得shell可以自主根据PATH变量需找可执行程序, 并且在将来可提供方法修改环境变量,如setenv, 达到灵活使用的目的,
我加入了如下内容:

//1.使用全局变量暂代环境变量char PATH[100]="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:.";//2.采用strtok方法分割环境变量,并通过循环不断尝试PATH中的路径char token[100] = "0"; strcpy(token, PATH);char * path_tem = strtok( token, ":");while (path_tem != NULL){    ...}//此处需要注意 char* 与 char[] 的区别

2. I/0重定向

此处需要注意open函数close函数以及权限的分配.

open函数打开文件操作使用系统调用函数open(),该函数的作用是建立一个文件描述符,其他的函数可以通过文件描述符对指定文件进行读取与写入的操作。头文件:#include <sys/types.h>    #include <sys/stat.h>    #include <fcntl.h>定义函数:        int open(const char * pathname, int flags);        int open(const char * pathname, int flags, mode_t mode);返回值:若所有欲核查的权限都通过了检查则返回0 值, 表示成功, 只要有一个权限被禁止则返回-1.mode参数只有在建立新文件时才会生效, 此外真正建文件时的权限会受到umask 值所影响, 因此该文件权限应该为 (mode-umask)

close函数关闭一个已打开的文件:#include <unistd.h>int close(int fd);返回值:成功返回0,出错返回-1并设置errno参数fd是要关闭的文件描述符.由open返回的文件描述符一定是该进程尚未使用的最小描述符.由于程序启动时自动打开文件描述符012,因此第一次调用open打开文件通常会返回描述符3,再调用open就会返回4。可以利用这一点在标准输入、标准输出或标准错误输出上打开一个新文件,实现重定向的功能。例如,首先调用close关闭文件描述符1,然后调用open打开一个常规文件,则一定会返回文件描述符1,这时候标准输出就不再是终端,而是一个常规文件了,再调用printf就不会打印到屏幕上,而是写到这个文件中了。

The parser already recognizes “>” and “<”

在给出代码中, cmd已被初始化, fd的值, file, 与mode都已分析完成, 只需直接传入 open函数即可

struct cmd*redircmd(struct cmd *subcmd, char *file, int type){  struct redircmd *cmd;  cmd = malloc(sizeof(*cmd));  memset(cmd, 0, sizeof(*cmd));  cmd->type = type;  cmd->cmd = subcmd;  cmd->file = file;  cmd->mode = (type == '<') ?  O_RDONLY : O_WRONLY|O_CREAT|O_TRUNC;  cmd->fd = (type == '<') ? 0 : 1;  return (struct cmd*)cmd;}

重定向完成代码如下:

    close(rcmd->fd);    if(open(rcmd->file, rcmd->mode, 0777) < 0)    {          fprintf(stderr, "Open :%s failed\n", rcmd->file);          exit(0);      }      runcmd(rcmd->cmd);  

3. 管道

0 0
原创粉丝点击