dvd-sector-copy.c: Secret option to dump the exact bad sectors encountered.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 19 Feb 2022 02:02:24 +0000 (02:02 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 19 Feb 2022 02:02:24 +0000 (02:02 +0000)
I don't think this one quite works properly yet.

dvd-sector-copy.c

index 36b5425..fd15138 100644 (file)
@@ -413,6 +413,7 @@ static dvd_reader_t *dvd;
 static int dvdfd = -1, outfd = -1;
 static dvd_file_t *vob;
 static const char *mapfile; static FILE *mapfp;
+static const char *errfile; static FILE *errfp;
 
 struct badblock { secaddr start, end; };
 DEFVEC(badblock_v, struct badblock);
@@ -479,7 +480,13 @@ static ssize_t read_sectors(secaddr pos, void *buf, secaddr want)
     }
 
     if (n > 0) { done += n; pos += n; p += n*SECTORSZ; want -= n; }
-    else if (!n || errno != EINTR) break;
+    else if (!n) break;
+    else if (errno == EIO && errfile) {
+      open_file_on_demand(errfile, &errfp, "bad-sector error log");
+      fprintf(errfp, "%"PRIuSEC" %"PRIuSEC"\n", pos, pos + 1);
+      check_write(errfp, "bad-sector error log");
+      break;
+    } else if (errno != EINTR) break;
   }
   if (fakeerr && !errno) errno = fakeerr;
   return (!done && errno ? -1 : done);
@@ -953,9 +960,10 @@ int main(int argc, char *argv[])
 
   p = strrchr(argv[0], '/'); prog = p ? p + 1 : argv[0];
   for (;;) {
-    opt = getopt(argc, argv, "hFR:X:b:cr:"); if (opt < 0) break;
+    opt = getopt(argc, argv, "hE:FR:X:b:cr:"); if (opt < 0) break;
     switch (opt) {
       case 'h': usage(stderr); exit(0);
+      case 'E': errfile = optarg; break;
       case 'F': f |= f_fixup; break;
       case 'R':
        fp = fopen(optarg, "r");
@@ -1205,6 +1213,7 @@ int main(int argc, char *argv[])
   if (dvdfd >= 0) close(dvdfd);
   if (outfd >= 0) close(outfd);
   carefully_fclose(mapfp, "bad-sector region map");
+  carefully_fclose(errfp, "bad-sector error log");
 
 #undef f_bogus
 #undef f_continue