#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:");
}
}