#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<fcntl.h> #define BUFFERSIZE 4096 #define COPYMODE 644 void oops(char *,char *); int main(int argc, char *argv[]) { int in_fd,out_fd,n_chars; char buf[BUFFERSIZE]; if((in_fd=open(argv[1],O_RDONLY))==-1) oops("can't 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 err from",argv[1]); if(close(in_fd)==-1||close(out_fd)==-1) oops("fail to close",""); return 0; } void oops(char *s1,char *s2) { fprintf(stderr,"Error : %s",s1); perror(s2); exit(1); }
注意: 1)關於系統調用 read和write屬於初級讀寫函數,也是系統調用;系統調用需要消耗大量時間。因為代碼執行權會從用戶轉移到內核,執行內核代碼是需要時間的。系統調用開銷巨大,因為系統調用需要特殊的內存和堆棧環境,這些需要在系統調用之前建立好;系統調用之後又需要恢復這些環境。這種環境切換需要耗費大量時間。最好的方法就是建立緩沖區,一次讀取大量數據,避免多次進行系統調用。我們可以用這個思想來改造前一篇中的who。 2)系統調用的錯誤處理 一般約定,系統調用open,write,lseek在出錯時會返回值-1。另外,系統調用都有自己的錯誤集,以open為例,打開文件不存在,沒有讀的權限,打開文件太多等等。內核通過全局變量errno來確定錯誤類型,其中哦功能error.h中規定了一些錯誤的宏。 a。可以根據errno來分別進行錯誤處理:
#include<error.h> extern int errno; int sample() { int fd; fd=open("file",O_RDONLY); if(fd==-1) { printf("can not open file:"); if(error== ENOENT) printf("there is no such file"); if (error==INTR) { printf("interrupted while opening file"); } ... } }
b.顯示錯誤信息: 可以利用perror來通過error來尋找錯誤信息。
#include<error.h> extern int errno; int sample() { int fd; fd=open("file",O_RDONLY); if(fd==-1) { perror("can not open file:"); } }