#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#ifndef _WIN32
#include <unistd.h>
#else
#include <io.h>
#endif
#include <string.h>
#include <libpmem.h>
#define BUF_LEN 4096
static void
do_copy_to_pmem(char *pmemaddr, int srcfd, off_t len)
{
char buf[BUF_LEN];
int cc;
while ((cc = read(srcfd, buf, BUF_LEN)) > 0) {
pmem_memcpy_nodrain(pmemaddr, buf, cc);
pmemaddr += cc;
}
if (cc < 0) {
perror("read");
exit(1);
}
pmem_drain();
}
static void
do_copy_to_non_pmem(char *addr, int srcfd, off_t len)
{
char *startaddr = addr;
char buf[BUF_LEN];
int cc;
while ((cc = read(srcfd, buf, BUF_LEN)) > 0) {
memcpy(addr, buf, cc);
addr += cc;
}
if (cc < 0) {
perror("read");
exit(1);
}
if (pmem_msync(startaddr, len) < 0) {
perror("pmem_msync");
exit(1);
}
}
int
main(int argc, char *argv[])
{
int srcfd;
struct stat stbuf;
char *pmemaddr;
size_t mapped_len;
int is_pmem;
if (argc != 3) {
fprintf(stderr, "usage: %s src-file dst-file\n", argv[0]);
exit(1);
}
if ((srcfd = open(argv[1], O_RDONLY)) < 0) {
perror(argv[1]);
exit(1);
}
if (fstat(srcfd, &stbuf) < 0) {
perror("fstat");
exit(1);
}
if ((pmemaddr = pmem_map_file(argv[2], stbuf.st_size,
PMEM_FILE_CREATE|PMEM_FILE_EXCL,
0666, &mapped_len, &is_pmem)) == NULL) {
perror("pmem_map_file");
exit(1);
}
if (is_pmem)
do_copy_to_pmem(pmemaddr, srcfd, stbuf.st_size);
else
do_copy_to_non_pmem(pmemaddr, srcfd, stbuf.st_size);
close(srcfd);
pmem_unmap(pmemaddr, mapped_len);
exit(0);
}