10 // XXX: Assuming block size == 512
12 int main(int argc, char **argv)
15 fprintf(stderr, "Usage: %s <from> <to>\n", argv[0]);
19 int fi = open(argv[1], O_RDONLY);
21 fprintf(stderr, "Cannot open source %s: %m\n", argv[1]);
25 int fo = open(argv[2], O_WRONLY);
27 fprintf(stderr, "Cannot open destination %s: %m\n", argv[1]);
32 if (fstat(fi, &sti) < 0 || fstat(fo, &sto) < 0) {
33 fprintf(stderr, "Stat failed: %m\n");
36 if (!S_ISBLK(sti.st_mode)) {
37 fprintf(stderr, "Input is not a block device\n");
40 if (!S_ISBLK(sto.st_mode)) {
41 fprintf(stderr, "Output is not a block device\n");
45 unsigned long leni, leno;
46 if (ioctl(fi, BLKGETSIZE, &leni) < 0 ||
47 ioctl(fo, BLKGETSIZE, &leno) < 0) {
48 fprintf(stderr, "Cannot get device size: %m\n");
52 fprintf(stderr, "Will not fit: %ld > %ld\n", leni, leno);
57 char *buf = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
58 if (buf == MAP_FAILED) {
59 fprintf(stderr, "Cannot mmap buffer: %m\n");
63 unsigned int remi = leni;
66 int s = (remi < BUFSIZE/512) ? remi : BUFSIZE/512;
67 int l = read(fi, buf, s*512);
69 fprintf(stderr, "Read error: %m\n");
73 fprintf(stderr, "Short read: %d of %d. Recovering.\n", l, s*512);
75 int w = write(fo, buf, l);
77 fprintf(stderr, "Write error: %m\n");
81 fprintf(stderr, "Short write: %d of %d\n", w, l);
86 printf("\rCopied %d of %d MB (%d%%)...", (int)((leni-remi)/2048), (int)((leni+2047)/2048),
87 (int)((double)(leni-remi) / leni * 100));
92 printf("Copied %d MB \n", (int)((leni+2047)/2048));