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[])
- {
- /* Check the command-line arguments */
- if (argc != 3) {
- fprintf(stderr, "usage: %s <filename> <line number>\n", argv[0]);
- return EXIT_FAILURE;
- }
- /* Open the file in read-write mode */
- int fd = open(argv[1], O_RDWR);
- if (fd < 0) {
- perror("open");
- return EXIT_FAILURE;
- }
- /* stat() the file to find the size */
- struct stat stat_buf;
- if (fstat(fd, &stat_buf) < 0) {
- perror("fstat");
- return EXIT_FAILURE;
- }
- /* Map the file into the current process's address space -- only works on
- regular files */
- 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;
- }
- /* Get the line number to remove from the second argument */
- int line = atoi(argv[2]);
- if (line < 1) {
- fprintf(stderr, "Line %d makes no sense.\n", line);
- return EXIT_FAILURE;
- }
- /* Find the nth line */
- char *linen = map;
- int i;
- for (i = 1; i < line; ++i) {
- /* Search for the next '\n' character. Assumes Linux newline encoding */
- 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;
- }
- /* Point to the character one past the newline */
- ++linen;
- }
- /* Find the (n + 1)th line */
- char *linen1 = memchr(linen, '\n', stat_buf.st_size - (linen - (char *)map));
- if (linen1) {
- /* We found the end of the line, so swallow the newline */
- ++linen1;
- /* Erase the line by copying the memory at linen1 to linen */
- memmove(linen, linen1, stat_buf.st_size - (linen1 - (char *)map));
- /* Unmap the file */
- if (munmap(map, stat_buf.st_size) < 0) {
- perror("munmap");
- return EXIT_FAILURE;
- }
- /* Shrink the file by the size of the nth line */
- if (ftruncate(fd, stat_buf.st_size - (linen1 - linen)) < 0) {
- perror("ftruncate");
- return EXIT_FAILURE;
- }
- } else {
- /* The nth line was the last line, so unmap the file */
- if (munmap(map, stat_buf.st_size) < 0) {
- perror("munmap");
- return EXIT_FAILURE;
- }
- /* Chop off the last line */
- if (ftruncate(fd, linen - (char *)map) < 0) {
- perror("ftruncate");
- return EXIT_FAILURE;
- }
- }
- /* Close the file */
- close(fd);
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment