Chinaunix首页 | 论坛 | 博客
  • 博客访问: 397582
  • 博文数量: 41
  • 博客积分: 696
  • 博客等级: 上士
  • 技术积分: 727
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-04 20:41
文章分类

全部博文(41)

文章存档

2012年(41)

分类: C/C++

2012-03-15 15:11:41

命令的实现

cp 命令的模拟实现

大家也都知道 cp 这个命令主要的作用就是把一个文件从一个位置复制到另一个位置。比如现在 /root 目录下有一个 test.txt 文件,如果我们用 cp test.txt test2.txt 命令的话,在同一个目录下面就会生成一个同样内容的 test2.txt 文件了。

那么 cp 命令是怎么实现的呢,我们看如下代码:

#include

#include

#include

#include

 

#define BUFFERSIZE 4096

 

void command_format(char *,char *);

 

int main(int argc,char *argv[])

{

         int fd_in,fd_out,n_chars;

         char buff[BUFFERSIZE];

        

         if(argc != 3)

         {

                   fprintf(stderr,"usage:%s source destination\n",*argv);

                   return 1;

         }

        

         if((fd_in=open(argv[1],O_RDONLY))==-1)

         {

                   command_format("cannot open",argv[1]);

         }

 

         if((fd_out=creat(argv[2],0644))==-1)

         {

                   command_format("cannot create",argv[2]);

         }

 

         while((n_chars=read(fd_in,buff,BUFFERSIZE))>0)

         {

                   if(write(fd_out,buff,n_chars)!=n_chars)

                   {

                            command_format("write error to",argv[2]);

                   }

         }

 

         if(n_chars==-1)

         {

                   command_format("read error from",argv[1]);

         }

 

         if(close(fd_in)==-1 || close(fd_out)==-1)

         {

                   command_format("error closing files"," ");

         }

         return 0;

}

 

void command_format(char *s1,char *s2)

{

         fprintf(stderr,"error:%s",s1);

         perror(s2);

}

该程序的主要实现思想是:打开一个输入文件,创建一个输出文件,建立一个 BUFFERSIZE 大小的缓冲区;然后在判断输入文件未完的循环中,每次读入多少就向输出文件中写入多少,直到输入文件结束。

命令实现的说明

让我来详细的讲述一下这个程序:

  • 开头四行包含了 4 个头文件, 文件包含了 fprintfperror 的函数原型定义; 文件包含了 readwrite 的函数原型定义; 文件包含了 opencreat 的函数原型定义、 文件包含了 exit 的函数原型定义。这些函数原型有些是系统调用、有些是库函数,通常都可以在 /usr/include 目录中找到这些头文件。
  • 接下来的 2 行以宏定义的方式定义了 12个常量。BUFFERSIZE 用来表示缓冲区的大小。
  • 接下来的一行定义了一个函数原型command_fromat,该函数的具体定义在最后出现,用来输出出错信息到 stderr,也就是标准错误输出的文件流。
  • 接下来主程序开始。首先定义了 2 个文件描述符、一个存放读出字节数的变量 n_chars、和一个 BUFFERSIZE 大小的字符数组用来作为拷贝文件的缓冲区。
  • 接下来判断输入参数的个数是否为 3,也就是程序名 argv[0]、拷贝源文件 argv[1]、目标文件 argv[2]。不为 3 的话就输出错误信息到 stderr,然后退出程序。
  • 接下来的 2 行,用 open 系统调用以 O_RDONLY 只读模式打开拷贝源文件,如果打开失败就输出错误信息并退出。如果想了解文件打开模式的详细内容请使用命令 man 2 open,来查看帮助文档。
  • 接下来的 2 行,用 creat 系统调用以0644 的权限建立一个文件,如果建立失败函数的返回值为 -1 的话,就输出错误信息并退出。
  • 接下来的循环是拷贝的主要过程。它从输入文件描述符 fd_in 中,读入 BUFFERSIZE 字节的数据,存放到 buf 字符数组中。在正常读入的情况下,read 函数返回实际读入的字节数,也就是说只要没有异常情况和文件没有读到结尾,那么 n_chars 中存放的就是实际读出的字节的数字。然后 write 函数将从 buf 缓冲区中,读出 n_chars 个字符,写入 fd_out 输出文件描述符。由于 write 系统调用返回的是实际写入成功的字节数。所以当读出 N 个字符,又成功写入 N 个字符到输出文件描述符中去的时候,就表示写成功了,否则就报告写入错误。
  • 最后就是用 close 系统调用关闭打开的输入和输出文件描述符。
阅读(2157) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~