Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/mman.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- int
- main(int argc, char *argv[])
- {
- if (argc != 3) {
- fprintf(stderr, "usage: %s <filename> <line number>\n", argv[0]);
- return EXIT_FAILURE;
- }
- int fd = open(argv[1], O_RDWR);
- if (fd < 0) {
- perror("open");
- return EXIT_FAILURE;
- }
- struct stat stat_buf;
- if (fstat(fd, &stat_buf) < 0) {
- perror("fstat");
- close(fd);
- return EXIT_FAILURE;
- }
- void *map = mmap(NULL, stat_buf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
- fd, 0);
- if (map == MAP_FAILED) {
- perror("mmap");
- return EXIT_FAILURE;
- }
- int line = atoi(argv[2]);
- if (line < 1) {
- fprintf(stderr, "Line %d makes no sense.\n", line);
- return EXIT_FAILURE;
- }
- char *linen = map;
- int i;
- for (i = 1; i < line; ++i) {
- linen = memchr(linen, '\n', stat_buf.st_size - (linen - (char *)map));
- if (!linen) {
- fprintf(stderr, "Line %d is past EOF.\n", line);
- return EXIT_FAILURE;
- }
- ++linen;
- }
- char *linen1 = memchr(linen, '\n', stat_buf.st_size - (linen - (char *)map));
- if (linen1) {
- ++linen1;
- memmove(linen, linen1, stat_buf.st_size - (linen1 - (char *)map));
- if (munmap(map, stat_buf.st_size) < 0) {
- perror("munmap");
- return EXIT_FAILURE;
- }
- if (ftruncate(fd, stat_buf.st_size - (linen1 - linen)) < 0) {
- perror("ftruncate");
- return EXIT_FAILURE;
- }
- } else {
- munmap(map, stat_buf.st_size);
- if (ftruncate(fd, linen - (char *)map) < 0) {
- perror("ftruncate");
- return EXIT_FAILURE;
- }
- }
- close(fd);
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment