mycp.c的功能与系统cp程序相同
将源文件复制到目标文件,例子如下:
要求使用系统调用open/read/write/close实现
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
$ ./mycp /etc/passwd passwd.bak
$ cat passwd.bak
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
程序需要接收命令行参数,argv[1]
和argv[2]
分别是原文件与待复制文件的文件路径。首先打开原文件,读取文件中的数据到内存缓冲区,关闭文件。然后打开待复制的文件(若不存在则创建,若已存在则将文件长度截断为0),将内存缓冲区的内容写入到该文件中,关闭文件。在打开文件、读取文件、写入文件时,若系统调用失败,调用panic
子函数打印报错信息并终止程序。
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
// 定义内存缓冲区大小
#define MAXSIZE 65536
// 当系统调用失败时,调用panic函数终止程序
// perror打印系统调用的报错信息
void panic(char *message) {
perror(message);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
char *path = argv[1];
char *cp_path = argv[2];
char buffer[MAXSIZE];
// 打开原文件,读取文件中的数据到内存缓冲区,关闭文件
int fd = open(path, O_RDONLY);
if(fd < 0)
panic("open");
int count = read(fd, buffer, sizeof(buffer));
if(count < 0)
panic("read");
close(fd);
// 打开待复制的文件(若不存在则创建),将内存缓冲区的内容写入到文件中,关闭文件
int fd_cp = open(cp_path, O_CREAT|O_WRONLY|O_TRUNC);
if(fd_cp < 0)
panic("open");
int count_cp = write(fd_cp, buffer, count);
if(count_cp < 0)
panic("write");
close(fd_cp);
return 0;
}
需要注意的是cat passwd.bak
命令需要在root
权限下执行
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
$ gcc mycp.c -o mycp
$ ./mycp /etc/passwd passwd.bak
$ cat passwd.bak
cat: passwd.bak: 权限不够
$ sudo cat passwd.bak
[sudo] (用户名XXX) 的密码:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...