閱讀源碼,幫助理解操作系統。
echo命令實現
從簡單的命令開始理解。echo命令,在下一行輸出echo後面輸入的文字。在xv6操作系統中,有單獨的echo.c文件,實現echo命令,文件核心代碼如下:
int main(int argc, char *argv[])
{
int i;
for(i = 1; i < argc; i++)
printf(1, "%s%s", argv[i], i+1 < argc ? " " : "\n");
exit();
}
實現代碼特別簡單,主要是講參數傳遞到printf函數,實現輸出。需要注意的是,echo程序入口是main()函數,表明這是一個完成的進程,入口爲main(),exit()結束進程。因此,當執行echo命令的時候,操作系統實際上涉及到了系統中斷和進程切換。
printf()函數,在printf.c文件中實現。printf.c文件中有三個函數,printf(),printint(),putc()。實際上,printf()調用printint(),putc()函數,printint()函數也調用putc()函數。因此,printf()函數主要以來putc()函數來實現。putc()函數代碼如下:
static void putc(int fd, char c)
{
write(fd, &c, 1);
}
putc()函數實際上有調用系統接口write()(也叫系統調用,system call)。接口具體說明可以見xv6系統調用。
cat命令實現
cat命令比echo命令要複雜一點,需要調用的系統接口函數也要多一點。由單獨的cat.c文件來實現函數功能。核心代碼如下:
void cat(int fd)
{
int n;
while((n = read(fd, buf, sizeof(buf))) > 0) {
if (write(1, buf, n) != n) {
printf(1, "cat: write error\n");
exit();
}
}
if(n < 0){
printf(1, "cat: read error\n");
exit();
}
}
int main(int argc, char *argv[])
{
int fd, i;
if(argc <= 1){
cat(0);
exit();
}
for(i = 1; i < argc; i++){
if((fd = open(argv[i], 0)) < 0){
printf(1, "cat: cannot open %s\n", argv[i]);
exit();
}
cat(fd);
close(fd);
}
exit();
}
具體來說,cat功能,首先調用open()函數,返回一個文件描述符,將該文件描述符號傳遞到read()函數,依次讀出512字節的文件內容,將該內容通過write()函數輸出到終端,知道文件內容全部讀完。再調用close()函數,關閉文件讀取。算是一個相對複雜的命令實現。