/* * Example of using memory-mapped I/O. * * Change all upper case in a text file to lower case, in place. * Name of file supplied as command-line argument. */ #include #include #include #include #include #include #include int main(int argc, char * argv[]) { if (argc != 2) { fprintf(stderr, "usage: %s filename\n", argv[0]); return EXIT_FAILURE; } int fd = open(argv[1], O_RDWR); if (fd == -1) { perror("open"); return EXIT_FAILURE; } struct stat file_stats; if (fstat(fd, &file_stats) == -1) { perror("fstat"); return EXIT_FAILURE; } off_t length = file_stats.st_size; char * mapped = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mapped == MAP_FAILED) { perror("mmap"); return EXIT_FAILURE; } long count = 0; for (off_t i = 0; i < length; ++i) { char ch = mapped[i]; if (isupper(ch)) { mapped[i] = tolower(ch); count += 1; } } if (msync(mapped, length, MS_SYNC) == -1) { perror("msync"); return EXIT_FAILURE; } if (munmap(mapped, length) == -1) { perror("munmap"); return EXIT_FAILURE; } close(fd); printf("%ld characters changed\n", count); return EXIT_SUCCESS; }