操作系统源码阅读 - 3 : 自定义命令

操作系统源码阅读 - 3 : 自定义命令


阅读源码,帮助理解操作系统。
上一篇: 操作系统源码阅读 - 2 : 基础命令与操作系统接口

head命令

在xv6系统上实现head命令。head命令用来显示开头某个数量的文字区块。在自定义实现中,head命令一共有三种形式。

head filename
head [-number] filename
head [-n] number filename

函数实现

具体实现上,考虑抽象为一个函数head(int fd, int number),用来实现读取文件描述符为fd的文件的前number行内容并输出。同时,在main()函数中,分别分析head命令的三种模式,并依次调用head()函数。实现文件为head.c,核心代码如下:

char buf[512];

void head(int fd,int line)
{
    int n, i;
    int tag = 0;

    while((n = read(fd,buf, sizeof(buf))) > 0)
    {
        for(i = 0;i < n;i ++)
        {
            if(buf[i] == '\n')
            {
                tag = tag + 1;
                if(tag == line)
                {
                    i = i + 1;
                    break;
                }
            }
        }
        if(write(1,buf, i) != i)
        {
            printf(1, "head: write error\n");
            exit();
        }
        if(tag == line)
        {
            break;
        }
    }
    if(n < 0)
    {
        printf(1,"head: read error\n");
        exit();
    }
}

int main(int argc, char * argv[])
{
    int fd;
    int line;
    
    if(argc < 2)
    {
        printf(1,"head: no parameters\n");
        exit();
    }
    else if (argc == 2)
    {
        if((fd = open(argv[1],0)) < 0)
        {
            printf(1,"head: cannot open %s\n", argv[1]);
            exit();
        }
        line = 10;
        head(fd,line);
        close(fd);
        exit();
    }
    else if (argc == 3)
    {
        if(argv[1][0]!= '-')
        {
            printf(1,"head: wrong parameters\n");
            exit();
        }
        else
        {
            line = 0;
            for(int i = 1;argv[1][i] != '\0';i ++)
            {
                int tem = (argv[1][i] - '0');
                line = line*10 + tem;
            }
            if((fd = open(argv[2],0)) < 0)
            {
                printf(1,"head: cannot open %s\n", argv[2]);
                exit();
            }
            head(fd,line);
            close(fd);
        }
        exit();
    }
    else
    {
        if(argv[1][0]!= '-'||argv[1][1]!='n'||argv[1][2]!='\0')
        {
            printf(1,"head: wrong parameters\n");
            exit();
        }
        else
        {
            line = 0;
            for(int i = 0;argv[2][i] != '\0';i ++)
            {
                int tem = (argv[2][i] - '0');
                line = line*10 + tem;
            }
            if((fd = open(argv[3],0)) < 0)
            {
                printf(1,"head: cannot open %s\n", argv[3]);
                exit();
            }
            head(fd,line);
            close(fd);
        }
        exit();
    }
}

参考cat命令的实现即可。

修改Makefile文件

实现head.c文件之后,需要将该文件添加到Makefile文件的编译序列中,具体修改如下:

UPROGS=\
	_cat\
	_echo\
	_forktest\
	_grep\
	_head\
	_init\
	_kill\
	_ln\
	_ls\
	_mkdir\
	_rm\
	_sh\
	_stressfs\
	_usertests\
	_wc\
	_zombie\
	## 添加_head\。当os运行时,通过ls命令可以找到head程序。

EXTRA=\
	mkfs.c ulib.c user.h cat.c echo.c forktest.c grep.c head.c kill.c\
	ln.c ls.c mkdir.c rm.c stressfs.c usertests.c wc.c zombie.c\
	printf.c umalloc.c\
	README dot-bochsrc *.pl toc.* runoff runoff1 runoff.list\
	.gdbinit.tmpl gdbutil\
	## 添加head.c。将head.c添加到编译队列

之后,按流程进行编译,运行即可。实验结果如下:
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值