最近,在看《深入理解计算机系统》,在看到虚拟存储器这一章节时,遇到一个习题:
编写一个C程序mmapcopy.c, 使用mmap将一个任意大小的磁盘文件拷贝到stdout。输出文件的名字必须作为一个命令行参数来传递。
google了一下,下面附上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> int main (int argc, char *argv[]) { struct stat sb; off_t len; char *p; int fd; if (argc < 2) { fprintf (stderr, "usage: %s <file>\n", argv[0]); return 1; } fd = open (argv[1], O_RDONLY); if (fd == -1) { perror ("open"); return 1; } if (fstat (fd, &sb) == -1) { perror ("fstat"); return 1; } if (!S_ISREG (sb.st_mode)) { fprintf (stderr, "%s is not a file\n", argv[1]); return 1; } p = mmap (0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); if (p == MAP_FAILED) { perror ("mmap"); return 1; } if (close (fd) == -1) { perror ("close"); return 1; } for (len = 0; len < sb.st_size; len++) putchar (p[len]); if (munmap (p, sb.st_size) == -1) { perror ("munmap"); return 1; } return 0; }
|
对于这个代码,下面附上我的收获:
- 以前写代码的时候很少考虑出错处理,在看到这段代码的时候,顿时收获良多
- fprintf stderr的用法很重要,同时要区别与stdout的关系(区别)
- 利用main函数进行命令行参数的传递,
int main (int argc, char *argv[])
,main函数 return 0 代表成功,return 非0 代表error
perror()
的用法:
函数perror()
用于抛出最近的一次系统错误信息,其原型如下:
void perror(char *string)
;
说明:perror()
用来将上一个函数发生错误的原因输出到标准错误(stderr)。参数string所指的字符串会先打印出,后面再加上错误原因字符串,此错误原因依照全局变量errno的值来决定要输出的字符串。
- fstat( ) returns information about a given file
- off_t代表文件的偏移,与size_t的区别和联系可参考stackoverflow
参考资料:
- safaribooksonline