/* * This programme was originally written by * Jeff Moyer * * Copyright (C) 2016, Red Hat, Inc. */ #define _GNU_SOURCE 1 #include #include #include #include #include #include #include #include #include void usage(char *prog) { fprintf(stderr, "usage: %s \n", prog); exit(1); } void err_exit(char *op, unsigned long len, char *s) { fprintf(stderr, "%s(%s) len %lu %s\n", op, strerror(errno), len, s); exit(1); } int main(int argc, char **argv) { int fd, fd2, ret, dio = 1; char *map; char *msg; char *sfile; char *dfile; unsigned long len, opt; if (argc < 5) usage(basename(argv[0])); while ((opt = getopt(argc, argv, "b")) != -1) dio = 0; sfile = argv[optind]; dfile = argv[optind + 1]; msg = argv[optind + 3]; len = strtoul(argv[optind + 2], NULL, 10); if (errno == ERANGE) err_exit("strtoul", 0, msg); /* Open source file and mmap*/ fd = open(sfile, O_RDWR, 0644); if (fd < 0) err_exit("open src", len, msg); map = (char *)mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (map == MAP_FAILED) err_exit("mmap", len, msg); if (dio == 1) { /* Open dest file with O_DIRECT */ fd2 = open(dfile, O_RDWR|O_DIRECT, 0644); if (fd2 < 0) err_exit("open dest", len, msg); } else { /* Open dest file without O_DIRECT */ fd2 = open(dfile, O_RDWR, 0644); if (fd2 < 0) err_exit("open dest", len, msg); } /* First, test storing to dest file from source mapping */ ret = write(fd2, map, len); if (ret != len) err_exit("write", len, msg); ret = fsync(fd2); if (ret != 0) err_exit("fsync", len, msg); ret = (int)lseek(fd2, 0, SEEK_SET); if (ret == -1) err_exit("lseek", len, msg); /* Next, test reading from dest file into source mapping */ ret = read(fd2, map, len); if (ret != len) err_exit("read", len, msg); ret = msync(map, len, MS_SYNC); if (ret < 0) err_exit("msync", len, msg); ret = munmap(map, len); if (ret < 0) err_exit("munmap", len, msg); ret = close(fd); if (ret < 0) err_exit("clsoe fd", len, msg); ret = close(fd2); if (ret < 0) err_exit("close fd2", len, msg); exit(0); }