本文章中的示例代碼是在 CentOS 5.4 64 位環境下運行通過的,在其它 unix 系統上沒有測試過。
Linux 操作系統中的命令實際上是編譯好的可執行程序,比如說 ls 這個命令,這個文件位於 /bin 目錄下面,當我們用 file /bin/ls 命令查看的時候會有以下輸出:
[root@localhost ~]# file /bin/ls /bin/ls: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped
這個命令通過調用 stat 系統調用和 /usr/share/file/magic.mgc 文件來決定文件的類型。如上的 /bin/ls 是一個 ELF 格式的動態鏈接的 64 位的可執行文件。
系統調用是用戶程序和操作系統內核之間的接口,我們可以使用操作系統提供的系統調用來請求分配資源和服務。我們可以通過 man 2 章節來查找 Linux 提供的系統調用的具體使用方法。有關文件操作的常見系統調用命令有:open、creat、close、read、write、lseek、opendir、readdir、mkdir、stat 等等。
cp 命令的實現
cp 命令的模擬實現
大家也都知道 cp 這個命令主要的作用就是把一個文件從一個位置復制到另一個位置。比如現在 /root 目錄下有一個 test.txt 文件,如果我們用 cp test.txt test2.txt 命令的話,在同一個目錄下面就會生成一個同樣內容的 test2.txt 文件了。
那麼 cp 命令是怎麼實現的呢,我們看如下代碼:
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #define BUFFERSIZE 4096 #define COPYMODE 0644 void oops(char *, char *); main(int argc, char * argv[]) { int in_fd, out_fd, n_chars; char buf[BUFFERSIZE]; if ( argc != 3 ){ fprintf( stderr, "usage: %s source destination\n", *argv); exit(1); } if ( (in_fd=open(argv[1], O_RDONLY)) == -1 ){ oops("Cannot open ", argv[1]); } if ( (out_fd=creat( argv[2], COPYMODE)) == -1 ){ oops( "Cannot creat", argv[2]); } while ( (n_chars = read(in_fd , buf, BUFFERSIZE)) > 0 ){ if ( write( out_fd, buf, n_chars ) != n_chars ){ oops("Write error to ", argv[2]); } } if ( n_chars == -1 ){ oops("Read error from ", argv[1]); } if ( close(in_fd) == -1 || close(out_fd) == -1 ) oops("Error closing files",""); } void oops(char *s1, char *s2) { fprintf(stderr,"Error: %s ", s1); perror(s2); exit(1); }
該程序的主要實現思想是:打開一個輸入文件,創建一個輸出文件,建立一個 BUFFERSIZE 大小的緩沖區;然後在判斷輸入文件未完的循環中,每次讀入多少就向輸出文件中寫入多少,直到輸入文件結束。
cp 命令實現的說明
讓我來詳細的講述一下這個程序: