操作系統源碼閱讀 - 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添加到編譯隊列

之後,按流程進行編譯,運行即可。實驗結果如下:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章