C语言实现Linux代码解释器

一.设计目的:熟悉Linux编程环境,加强对Linux命令的理解及函数的运用

二.设计内容:在Linux环境下模拟实现简单命令解释器(即定义一个命令使它具有Linux中某些命令的功能)
例如:定义mydir使它具有dir 的功能
即在Linux环境中 $ mydir 和 $dir 作用一样
就实现了dir命令的解释。
(1)要求实现的基本命令包括:
定义 mypwd 具有 pwd //显示当前所在目录的路径名
定义 mylist 具有 list //列出指定目录名中的所有目录及文件
定义 mycd 具有 cd //改变当前工作目录
定义 mymkdir 具有 mkdir //新建目录
定义 myrmdir 具有 rmdir //删除目录
定义 myexit 具有 exit //退出命令解释程序
(2)可选做的扩展命令包括:
定义 myrename 具有 rename <旧文件名> <新文件名> //重命名一个文件或目录
定义mycopy 具有 copy <已存在的文件名> <副本文件名或路径> //复制一个已存在的文件
定义myfind 具有 find <目录> -name <待查找的文件名> //在指定的目录及其子目录中查找指定的文件(输入文件名),并输出查找到的文件的绝对路径。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
/*
 *           实现dir功能的函数
 */
void do_ls(char dirname[])
{
              DIR* dir_ptr;   /* the dirname */
              struct dirent* direntp; /* each entry */
              if ((dir_ptr = opendir(dirname)) == NULL)
             {
                        fprintf(stderr, "ls1: cannot open %s\n", dirname);
              }
              else
              {
                         while ((direntp = readdir(dir_ptr)) != NULL)
                         {
                             printf("%s\n", direntp->d_name);
                          }
                         closedir(dir_ptr);
                     }
}
/*
*      实现mycd功能的函数
*/
bool mycd(char path[])  {
                if(chdir(path)==0)
                  {
                              return true;
                    }
                  else
                     {
                              return false;
                     }
}
/*
*         实现mycopy功能的函数
*/
#define BUFFERSIZE 4096//定义存储器容量
#define COPYMODE 0644//定义复制的长度

void mycopy(int argc, char *argv[])
{
                         int in_fd, out_fd, n_chars;//三个描述符值
                         char buf[BUFFERSIZE];//存储器位置

                         /*cp的参数有两个,分别是要复制的文件,和目的目录,这样一共应该是有三个操作数
                           所以要先检查argc的值是否为三,如果不是,返回标准错误*/
                          if (argc != 3){
                                    fprintf(stderr, "usage: %s source destination\n", *argv);
                                     exit(1);
                           }
                          /*检查cp的第一个参数,要复制的文件,用open打开,in_fd为open返回的描述符
                          如果返回-1,代表打开失败,提示错误*/
                         if ((in_fd = open(argv[1], O_RDONLY)) == -1)
                                      printf("Cannot open %s\n", argv[1]);
                                /*检查cp的第二个参数,复制的目的地址,用create在目的地址创建新文件,out_fd为open返回的描述符
                                   如果返回-1,代表创建失败,提示错误*/
                         if ((out_fd = creat(argv[2], COPYMODE)) == -1)
                                            printf("Cannot creat %s\n", argv[2]);
                       /*cp指令的动作就是读取一个文件的内容到存储器,在新的地址创建空白文件,再从存储器将内容写入新文件。
                           这里判断复制是否成功:
                           如果能读取顺利,而读取的位数和写的位数不同,是写错误;
                           如果读取失败,是读错误。*/
                           while ((n_chars = read(in_fd, buf, BUFFERSIZE)) > 0)
                                         if (write(out_fd, buf, n_chars) != n_chars)
                                                  printf("Write error to %s\n", argv[2]);
                            if (n_chars == -1)
                                         printf("Read error from %s\n", argv[1]);
                         /*这里执行的是关闭文件的动作,in_fd和out_fd两个文件描述符
                               所指向的文件只要有一个关闭错误,就提示关闭错误。*/
                           if (close(in_fd) == -1 || close(out_fd) == -1)
                                      printf("Error closing files\n");
}
/*这个是用来输出错误信息的函数*/
void oops(char *s1, char *s2)
{
                             fprintf(stderr, "Error: %s ", s1);
                             perror(s2);//用来将上一个函数发生错误的原因输出到标准设备(stderr)
                             exit(1);
}
/*
*      实现mydel功能的函数
*/
bool mydel(char dir[]) {
                    if(rmdir(dir)==0)
                       {
                            return true;
                        }
                    else {
                              return false;
                         }
}
/*
*      实现pwd功能的函数
*/
ino_t get_inode(char *filename);
void printpathto(ino_t);
void inum_to_name(ino_t inode_to_find, char *namebuf, int buflen);

/*
* prints path leading down to an object with this inode
* kind of recursive
*/
void printpathto(ino_t this_inode)
{
                            ino_t my_inode;
                            char its_name[BUFSIZ];
                            if (get_inode("..") != this_inode)
                            {
                                  chdir("..");       /* up one dir */
                                  inum_to_name(this_inode, its_name, BUFSIZ);     /* get its name */
                                  my_inode = get_inode(".");       /* print head */
                                  printpathto(my_inode);      /* recursively */
                                  printf("/%s", its_name);        /* now print name of this */
                             }
}
void inum_to_name(ino_t inode_to_find, char *namebuf, int buflen)
{
           DIR *dir_ptr;   /* the directory */
           struct dirent *direntp; /* each entry */
           dir_ptr = opendir(".");
           if (dir_ptr == NULL)
           {
             perror(".");
             exit(1);
            }
              /* search directory for a file with specified inum */
            while ((direntp = readdir(dir_ptr)) != NULL)
            {
                        if (direntp->d_ino == inode_to_find)
                        {
                             strncpy(namebuf, direntp->d_name, buflen);
                             namebuf[buflen - 1] = '\0'; /* just in case */
                             closedir(dir_ptr);
                             return;
                         }
            }
            fprintf(stderr, "error looking for inum %ld\n", inode_to_find);
            exit(1);
}

/*
*      returns inode number of the file
*/
ino_t get_inode(char *filename)
{
        struct stat info;
        if (stat(filename, &info) == -1)
        {
                  fprintf(stderr, "Cannot stat");
                  perror(filename);
                  exit(1);
         }
         return info.st_ino;
}
//主程序
int main(int argc, char *argv[])
{
               char command[20];
               char c;
               int i=1;
               do{
                       printf("请输入命令:");
                       scanf("%s",&command);
                       if(strcmp(command,"mydir") == 0)
                       {
                               if (argc == 1)
                                            do_ls(".");
                               else
                               {
                              while (--argc)
                              {
                               printf("%s:\n", *(++argv));
                               do_ls(*argv);
                               }
                         }
                    }
else if(strcmp(command,"mycd") == 0)
{
              char path[20];
              scanf("%s",&path);
              if(!mycd(path))
              {
                           printf("mycd:%s:没有那个目录\n",path);
               }
}
else if(strcmp(command,"mycopy") == 0)
{
                     char filename1[20];
                     char filename2[20];
                     scanf("%s",&filename1);
                     scanf("%s",&filename2);
                     argc=3;
                     argv[1]=filename1;
                     argv[2]=filename2;
                     argv[3]=NULL;
                     mycopy(argc,argv);
}
else if(strcmp(command,"mydel") == 0)
{
                 char dir[20];
                 scanf("%s",&dir);
                 if(!mydel(dir))
                 {
                          printf("mydel:无法删除%s:没有那个目录\n",dir);
                  }
}
else if(strcmp(command,"mypwd") == 0)
{
                  printpathto(get_inode("."));    /* print path to here */
                  putchar('\n');  /* then add newline */
}
else
{
                  printf("input error!\n");
}
printf("是否继续操作(Y/N)?");
fflush(stdin);
scanf("\n%c",&c);
if(c=='N' || c=='n')
{
          i=0;
}
printf("\n");
}while(i!=0);
           return 0;
}
  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值