设为首页 加入收藏

TOP

Linux 下几个文件操作命令的代码实现(一)
2011-03-18 13:01:29 】 浏览:3995
Tags:Linux 文件 操作 命令 代码 实现

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 命令是怎么实现的呢,我们看如下代码:


清单 1. 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 命令实现的说明

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

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


rm 命令的实现

rm 命令的模拟实现

rm 命令主要是用来删除一个文件。

该命令的实现代码如下:


清单 2. rm 命令代码
#include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(int argc , char * argv[]) { int rt; if(argc != 2){ exit(2); }else{ if((rt = unlink(argv[1])) != 0){ fprintf(stderr,"error."); exit(3); } } return 0; }

其中程序的关键是 unlink 系统调用,unlink 函数原型包含在 <unistd.h> 头文件里面。

用 strace 来跟踪命令

我们从这个程序的创建过程来分析这个程序。

这个命令的模拟程序是怎么写出来的呢?

首先,我们可以在机器上 touch test 建立一个 test 文件,然后调用 strace rm test 命令来查看 rm 命令具体使用了那些系统调用。

通过查看,我们看到主要使用的系统调用如下:

[root@localhost aa]# strace rm test execve("/bin/rm", ["rm", "test"], [/* 24 vars */]) = 0 brk(0) = 0xcc66000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aff83ffb000 uname({sys="Linux", node="localhost.localdomain", ...}) = 0 ... ... lstat("test", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C 编程最佳实践 下一篇Linux 中的零拷贝技术,第 2 部分

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目