Created
June 25, 2018 13:09
-
-
Save sanbrother/29af6eff94e645ece35425e120bdb497 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/mman.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#define handle_error(msg) \ | |
do { perror(msg); exit(EXIT_FAILURE); } while (0) | |
int | |
main(int argc, char *argv[]) | |
{ | |
char *addr; | |
int fd; | |
struct stat sb; | |
off_t offset, pa_offset; | |
size_t length; | |
ssize_t s; | |
if (argc < 3 || argc > 4) { | |
fprintf(stderr, "%s file offset [length]\n", argv[0]); | |
exit(EXIT_FAILURE); | |
} | |
fd = open(argv[1], O_RDONLY); | |
if (fd == -1) { | |
handle_error("open"); | |
} | |
if (fstat(fd, &sb) == -1) { | |
/* To obtain file size */ | |
handle_error("fstat"); | |
} | |
offset = atoi(argv[2]); | |
/* offset for mmap() must be page aligned */ | |
pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1); | |
if (offset >= sb.st_size) { | |
fprintf(stderr, "offset is past end of file\n"); | |
exit(EXIT_FAILURE); | |
} | |
if (argc == 4) { | |
length = atoi(argv[3]); | |
if (offset + length > sb.st_size) { | |
/* Can't display bytes past end of file */ | |
length = sb.st_size - offset; | |
} | |
} else { | |
/* No length arg ==> display to end of file */ | |
length = sb.st_size - offset; | |
} | |
addr = mmap(NULL, length + offset - pa_offset, PROT_READ, MAP_PRIVATE, fd, pa_offset); | |
if (addr == MAP_FAILED) { | |
handle_error("mmap"); | |
} | |
s = write(STDOUT_FILENO, addr + offset - pa_offset, length); | |
if (s != length) { | |
if (s == -1) { | |
handle_error("write"); | |
} | |
fprintf(stderr, "partial write"); | |
exit(EXIT_FAILURE); | |
} | |
munmap(addr, length + offset - pa_offset); | |
close(fd); | |
exit(EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment