Guest User

tavianator

a guest
Dec 21st, 2010
1,024
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.76 KB | None | 0 0
  1. #include <unistd.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <sys/mman.h>
  5. #include <fcntl.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9.  
  10. int
  11. main(int argc, char *argv[])
  12. {
  13.   if (argc != 3) {
  14.     fprintf(stderr, "usage: %s <filename> <line number>\n", argv[0]);
  15.     return EXIT_FAILURE;
  16.   }
  17.  
  18.   int fd = open(argv[1], O_RDWR);
  19.   if (fd < 0) {
  20.     perror("open");
  21.     return EXIT_FAILURE;
  22.   }
  23.  
  24.   struct stat stat_buf;
  25.   if (fstat(fd, &stat_buf) < 0) {
  26.     perror("fstat");
  27.     close(fd);
  28.     return EXIT_FAILURE;
  29.   }
  30.  
  31.   void *map = mmap(NULL, stat_buf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
  32.                    fd, 0);
  33.   if (map == MAP_FAILED) {
  34.     perror("mmap");
  35.     return EXIT_FAILURE;
  36.   }
  37.  
  38.   int line = atoi(argv[2]);
  39.   if (line < 1) {
  40.     fprintf(stderr, "Line %d makes no sense.\n", line);
  41.     return EXIT_FAILURE;
  42.   }
  43.  
  44.   char *linen = map;
  45.   int i;
  46.   for (i = 1; i < line; ++i) {
  47.     linen = memchr(linen, '\n', stat_buf.st_size - (linen - (char *)map));
  48.     if (!linen) {
  49.       fprintf(stderr, "Line %d is past EOF.\n", line);
  50.       return EXIT_FAILURE;
  51.     }
  52.     ++linen;
  53.   }
  54.  
  55.   char *linen1 = memchr(linen, '\n', stat_buf.st_size - (linen - (char *)map));
  56.   if (linen1) {
  57.     ++linen1;
  58.     memmove(linen, linen1, stat_buf.st_size - (linen1 - (char *)map));
  59.     if (munmap(map, stat_buf.st_size) < 0) {
  60.       perror("munmap");
  61.       return EXIT_FAILURE;
  62.     }
  63.     if (ftruncate(fd, stat_buf.st_size - (linen1 - linen)) < 0) {
  64.       perror("ftruncate");
  65.       return EXIT_FAILURE;
  66.     }
  67.   } else {
  68.     munmap(map, stat_buf.st_size);
  69.     if (ftruncate(fd, linen - (char *)map) < 0) {
  70.       perror("ftruncate");
  71.       return EXIT_FAILURE;
  72.     }
  73.   }
  74.  
  75.   close(fd);
  76.   return EXIT_SUCCESS;
  77. }
Advertisement
Add Comment
Please, Sign In to add comment