tfc_random: proper write error handling plus handling -E option.
authorAndrey Rys <rys@lynxlynx.ru>
Sat, 26 Jan 2019 10:15:54 +0000 (17:15 +0700)
committerAndrey Rys <rys@lynxlynx.ru>
Sat, 26 Jan 2019 10:16:38 +0000 (17:16 +0700)
VERSION
tfc_random.c

diff --git a/VERSION b/VERSION
index 7ed6ff82de6bcc2a78243fc9c54d3ef5ac14da69..1e8b314962144c26d5e0e50fd29d2ca327864913 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5
+6
index 4b82aee99de018504f09a0686dd43afb1a24ab7e..0e90f48be408eda3a2bab9d2cec53122955dc85a 100644 (file)
@@ -83,8 +83,10 @@ void tfc_getrandom(void *buf, size_t sz)
 
 void gen_write_bytes(const char *foutname, tfc_fsize offset, tfc_fsize nrbytes)
 {
+       static tfc_fsize wrpos = NOFSIZE;
        int fd, x;
-       size_t lblock;
+       size_t lblock, lio, lrem;
+       tfc_byte *pblk;
 
        for (x = 1; x < NSIG; x++) signal(x, SIG_IGN);
        memset(&sigact, 0, sizeof(sigact));
@@ -140,13 +142,33 @@ void gen_write_bytes(const char *foutname, tfc_fsize offset, tfc_fsize nrbytes)
        do_stop = NO;
        while (1) {
                if (do_stop) break;
-               lblock = blk_len_adj(nrbytes, total_processed_src, sizeof(srcblk));
+               pblk = srcblk;
+               lblock = lrem = blk_len_adj(nrbytes, total_processed_src, blksize);
 
                if (ctr_mode != TFC_MODE_PLAIN) tfc_getrandom(srcblk, lblock);
 
-               if (write(fd, srcblk, lblock) == -1)
-                       xerror(NO, NO, YES, "%s", foutname);
+               if (error_action == TFC_ERRACT_SYNC) wrpos = tfc_fdgetpos(fd);
+_wagain:       lio = write(fd, pblk, lrem);
+               if (lio == NOSIZE) {
+                       if (errno != EIO && catch_all_errors != YES)
+                               xerror(NO, NO, YES, "%s", foutname);
+                       switch (error_action) {
+                               case TFC_ERRACT_CONT: xerror(YES, NO, YES, "%s", foutname); goto _wagain; break;
+                               case TFC_ERRACT_SYNC:
+                               case TFC_ERRACT_LSYNC:
+                                       xerror(YES, NO, YES, "%s", foutname);
+                                       if (wrpos == NOFSIZE) lseek(fd, lblock, SEEK_CUR);
+                                       else lseek(fd, wrpos + lblock, SEEK_SET);
+                                       break;
+                               default: xerror(NO, NO, YES, "%s", foutname); break;
+                       }
+               }
                if (do_fsync && fsync(fd) == -1) xerror(NO, NO, YES, "%s", foutname);
+               if (lio < lrem) {
+                       pblk += lio;
+                       lrem -= lio;
+                       goto _wagain;
+               }
 
                total_processed_src += lblock;
                delta_processed += lblock;