编写Linux的cp指令

这是《Unix/Linux编程实践教程》上的第三个例子。这个程序从逻辑上比前两个简单很多,打开源文件、创建目标文件,剩下的就跟搬砖一样。代码注释放在文末,先说说我学到的:

1.关于变量n_chars

我们先看一看这个变量所处位置的功能,是通过read从文件中缓冲BUFFERSIZE个字节,把read的返回值赋值给n_chars。

是不是多此一举呢?若文件足够大,每次缓冲都能从文件中读出BUFFERSIZE个字节,那么这一步赋值只是把BUFFERSIZE传给n_chars,没什么用。关键就在于缓冲的最后一下,即文件末尾的那一下,这一次缓冲往往达不到BUFFERSIZE这么多。在这种情况下,若还写这么多,超出来的就成了无用数据,破坏了文件。要防止这种情况,就通过n_chars来记录每一次read读回来的字节数(只有在最后一下才有实际意义),这样就保证了前面都按照BUFFERSIZE缓冲,最后按照实际的剩余数缓冲。

2.opps函数

利用这个函数来显示出错信息。它有两个参数,前一个是出错的具体内容,后一个是跟错误有关的参数。利用系统调用出错时返回-1这个特点,就可以确定出错的具体位置,从而确定具体内容。

3.正事都是在while的条件判别式里做的

对于一个拷贝函数,最基本的功能就是缓冲了。我发现像这种重复劳动,就把它放到while的判别式里,到了条件就让它自动跳出来,而把每一次的劳动结果(比如缓冲),放在循环体里进行。

4.程序里还有一些跟错误有关的,还不太明白的说……
程序源码如下:

[c]

//cp

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>

//每次缓冲4096个字节
#define BUFFERSIZE    4096

//创建目标文件时的权限
#define COPYMODE    0644

//当文件访问出错时,调用它在屏幕上

//显示出错的具体信息
void opps(char *,char *);

main(int ac,char *av[])
{
int in_fd,out_fd,n_chars;

//负责缓冲的数组
char buf[BUFFERSIZE];

//ac为三时,代表有两个参数,符合要求

//ac不为三是,说明参数多余或少于两个,算出错处理
if( ac!=3){
fprintf(stderr,"usage:%s source destinationn",*av);
exit(1);
}

//一下各种opps,其实正事都是在条件判别式里进行的= =
if((in_fd=open(av[1],O_RDONLY)) == -1 )
opps("Cannot open",av[1]);
if((out_fd=creat(av[2],COPYMODE)) == -1 )
opps("Cannot creat",av[2]);
while((n_chars=read(in_fd,buf,BUFFERSIZE))>0)
if(write(out_fd,buf,n_chars)!= n_chars)
opps("Write error to",av[2]);
if(n_chars == -1)
opps("Read error from",av[1]);
if(close(in_fd) == -1 || close(out_fd) == -1)
opps("Error closing files","");
}

void opps(char * s1,char *s2)
{
fprintf(stderr,"Error: %s",s1);
perror(s2);
exit(1);
}

[/c]