1: /*
2: author:justinzhang
3: email:uestczhangchao@gmail.com
4: time:2012-8-22 16:23:08
5: desc: mmap()practice from man mmap
6: */
7: #include <sys/mman.h>
8: #include <sys/stat.h>
9: #include <fcntl.h>
10: #include <stdio.h>
11: #include <stdlib.h>
12: #include <unistd.h>
13:
14: #define handle_error(msg)\
15: do { perror(msg); exit(EXIT_FAILURE); } while(0)
16: int
17: main(int argc, char *argv[])
18: {
19: char *addr;
20: int fd;
21: struct stat sb;
22: off_t offset, pa_offset;
23: size_t length;
24: ssize_t s;
25: if(argc <3 || argc > 4)
26: {
27: fprintf(stderr, "%s file offset [length]\n",argv[0]);
28: exit(EXIT_FAILURE);
29: }
30: fd = open(argv[1],O_RDONLY);
31: if(fd == -1)
32: {
33: handle_error("open");
34: }
35: if(fstat(fd, &sb) == -1)/*to obtain file size*/
36: {
37: handle_error("fstat");
38: }
39: offset = atoi(argv[2]);
40: pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE)-1);
41: /*offset for mmap() must be page aligned*/
42: if( offset >= sb.st_size)
43: {
44: fprintf(stderr, "offset is past end of file\n");
45: exit(EXIT_FAILURE);
46: }
47: if(argc == 4)
48: {
49: length = atoi(argv[3]);
50: if(offset + length > sb.st_size)
51: length = sb.st_size - offset;
52: /*can't display bytes past end of file*/
53: }else {/*No length arg ==> display to end of file*/
54: length = sb.st_size - offset;
55: }
56: addr = mmap(NULL, length + offset - pa_offset, PROT_READ,MAP_PRIVATE, fd
57: ,pa_offset);
58: if(addr == MAP_FAILED)
59: handle_error("mmap");
60: s = write(STDOUT_FILENO, addr + offset - pa_offset, length);
61: if (s != length)
62: {
63: if (s == -1)
64: handle_error("write");
65: fprintf(stderr, "partial write");
66: exit(EXIT_FAILURE);
67: }
68: exit(EXIT_SUCCESS);
69: }