From 429747d78e7e60b3dc44fd8b23f1626c386663e0 Mon Sep 17 00:00:00 2001 From: Andrey Rys Date: Sat, 26 Jan 2019 19:32:41 +0700 Subject: [PATCH] tfc_io: xread and xwrite, which transparently handle EINTR case. --- VERSION | 2 +- tfc_base64.c | 6 +++--- tfc_io.c | 23 +++++++++++++++++++++++ tfc_random.c | 4 ++-- tfc_skein.c | 4 ++-- tfcrypt.c | 32 ++++++++++++++++---------------- tfcrypt.h | 3 +++ 7 files changed, 50 insertions(+), 24 deletions(-) create mode 100644 tfc_io.c diff --git a/VERSION b/VERSION index 1e8b314..7f8f011 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6 +7 diff --git a/tfc_base64.c b/tfc_base64.c index 2498004..f1d68f6 100644 --- a/tfc_base64.c +++ b/tfc_base64.c @@ -69,7 +69,7 @@ void do_edbase64(char **fargv) lblock = lrem = do_edcrypt == TFC_DO_DECRYPT ? TFC_B64_DWIDTH : TFC_B64_EWIDTH; ldone = 0; if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd); -_again: lio = read(sfd, pblk, lrem); +_again: lio = xread(sfd, pblk, lrem); if (lio == 0) do_stop = YES; if (lio != NOSIZE) ldone += lio; else { @@ -113,13 +113,13 @@ _again: lio = read(sfd, pblk, lrem); } lrem = ldone; ldone = 0; -_wagain: lio = write(dfd, pblk, lrem); +_wagain: lio = xwrite(dfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else xerror(NO, NO, NO, "%s", fargv[1]); if (do_edcrypt == TFC_DO_ENCRYPT) { size_t t; if (lread >= lblock || do_stop == TFC_STOP_FULL) { - t = write(dfd, "\n", 1); + t = xwrite(dfd, "\n", 1); if (t != NOSIZE) lio += t; else lio = NOSIZE; } diff --git a/tfc_io.c b/tfc_io.c new file mode 100644 index 0000000..2d3fd30 --- /dev/null +++ b/tfc_io.c @@ -0,0 +1,23 @@ +#include "tfcrypt.h" + +size_t xread(int fd, void *data, size_t szdata) +{ + size_t x; + + do { + x = (size_t)read(fd, data, szdata); + } while (x == NOSIZE && errno == EINTR); + + return x; +} + +size_t xwrite(int fd, const void *data, size_t szdata) +{ + size_t x; + + do { + x = (size_t)write(fd, data, szdata); + } while (x == NOSIZE && errno == EINTR); + + return x; +} diff --git a/tfc_random.c b/tfc_random.c index 0e90f48..7c7b0b9 100644 --- a/tfc_random.c +++ b/tfc_random.c @@ -44,7 +44,7 @@ static void get_urandom(const char *src, void *buf, size_t size) if (fd == -1) fd = open("/dev/random", O_RDONLY); if (fd == -1) xerror(NO, YES, YES, "random source is required (tried %s)", src); -_again: rd = read(fd, ubuf, sz); +_again: rd = xread(fd, ubuf, sz); if (rd < sz && rd != NOSIZE) { ubuf += rd; sz -= rd; @@ -148,7 +148,7 @@ void gen_write_bytes(const char *foutname, tfc_fsize offset, tfc_fsize nrbytes) if (ctr_mode != TFC_MODE_PLAIN) tfc_getrandom(srcblk, lblock); if (error_action == TFC_ERRACT_SYNC) wrpos = tfc_fdgetpos(fd); -_wagain: lio = write(fd, pblk, lrem); +_wagain: lio = xwrite(fd, pblk, lrem); if (lio == NOSIZE) { if (errno != EIO && catch_all_errors != YES) xerror(NO, NO, YES, "%s", foutname); diff --git a/tfc_skein.c b/tfc_skein.c index 6c595e1..b3b2019 100644 --- a/tfc_skein.c +++ b/tfc_skein.c @@ -78,7 +78,7 @@ tfc_yesno skeinfd(void *hash, size_t bits, const void *key, int fd, tfc_fsize re lblock = lrem = blk_len_adj(readto, total, TFC_BLKSIZE); ldone = 0; if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(fd); -_again: lio = read(fd, pblk, lrem); +_again: lio = xread(fd, pblk, lrem); if (lio == 0) stop = YES; if (lio != NOSIZE) ldone += lio; else { @@ -289,7 +289,7 @@ _dohash: if (status_timer) setup_next_alarm(status_timer); for (y = 0; y < sksum_turns; y++) skein(hash, bits, mackey_opt ? mackey : NULL, hash, TF_FROM_BITS(bits)); } if (do_outfmt == TFC_OUTFMT_B64) tfc_printbase64(stdout, hash, TF_FROM_BITS(bits), 0); - else if (do_outfmt == TFC_OUTFMT_RAW) write(1, hash, TF_FROM_BITS(bits)); + else if (do_outfmt == TFC_OUTFMT_RAW) xwrite(1, hash, TF_FROM_BITS(bits)); else mhexdump(hash, TF_FROM_BITS(bits), TF_FROM_BITS(bits), 0); if (do_outfmt != TFC_OUTFMT_RAW) { if (quiet == NO || xx > 1) tfc_say("\t%s", fargv[x] ? fargv[x] : "-"); diff --git a/tfcrypt.c b/tfcrypt.c index 07939a7..8608cf1 100644 --- a/tfcrypt.c +++ b/tfcrypt.c @@ -482,7 +482,7 @@ int main(int argc, char **argv) if (!strcmp(saltf, "-")) saltfd = 0; else saltfd = open(saltf, O_RDONLY | O_LARGEFILE); if (saltfd == -1) xerror(NO, NO, YES, "%s", saltf); - lio = read(saltfd, tfc_salt, TFC_MAX_SALT - TF_FROM_BITS(TFC_KEY_BITS)); + lio = xread(saltfd, tfc_salt, TFC_MAX_SALT - TF_FROM_BITS(TFC_KEY_BITS)); if (lio == NOSIZE) xerror(NO, NO, YES, "%s", saltf); tfc_saltsz = lio; xclose(saltfd); @@ -506,7 +506,7 @@ _nosalt: ldone = 0; lrem = lblock = sizeof(tmpdata); if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(mkfd); -_mkragain: lio = read(mkfd, pblk, lrem); +_mkragain: lio = xread(mkfd, pblk, lrem); if (lio == 0) do_stop = YES; if (lio != NOSIZE) ldone += lio; else { @@ -593,7 +593,7 @@ _mkragain: lio = read(mkfd, pblk, lrem); if (!strcmp(tweakf, "-")) twfd = 0; else twfd = open(tweakf, O_RDONLY | O_LARGEFILE); if (twfd == -1) xerror(NO, NO, YES, "%s", tweakf); - lio = ldone = read(twfd, key+TF_FROM_BITS(TF_MAX_BITS)+TF_SIZE_UNIT, 2*TF_SIZE_UNIT); + lio = ldone = xread(twfd, key+TF_FROM_BITS(TF_MAX_BITS)+TF_SIZE_UNIT, 2*TF_SIZE_UNIT); if (lio == NOSIZE) xerror(NO, NO, YES, "%s", tweakf); if (ldone < 2*TF_SIZE_UNIT) xerror(NO, NO, YES, "%s: %zu bytes tweak required", tweakf, 2*TF_SIZE_UNIT); @@ -642,7 +642,7 @@ _nokeyfd: if (!strcmp(counter_file, "-")) ctrfd = 0; else ctrfd = open(counter_file, O_RDONLY | O_LARGEFILE); if (ctrfd == -1) xerror(NO, NO, YES, "%s", counter_file); - lio = read(ctrfd, ctr, ctrsz); + lio = xread(ctrfd, ctr, ctrsz); if (lio == NOSIZE) xerror(NO, NO, YES, "%s", counter_file); if (lio < ctrsz) xerror(NO, YES, YES, "counter file is too small (%zu)!", lio); xclose(ctrfd); @@ -652,7 +652,7 @@ _nokeyfd: ldone = 0; lrem = lblock = ctrsz; if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd); -_ctrragain: lio = read(sfd, pblk, lrem); +_ctrragain: lio = xread(sfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else { if (errno != EIO && catch_all_errors != YES) @@ -697,7 +697,7 @@ _ctrskip1: _xts2key: ldone = 0; lrem = lblock = TF_FROM_BITS(TFC_KEY_BITS); if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(kfd); -_keyragain: lio = read(kfd, pblk, lrem); +_keyragain: lio = xread(kfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else { if (errno != EIO && catch_all_errors != YES) @@ -840,7 +840,7 @@ _pwdagain: memset(&getps, 0, sizeof(struct getpasswd_state)); if (!strcmp(genkeyf, "-")) krfd = 1; else krfd = open(genkeyf, O_WRONLY | O_CREAT | O_LARGEFILE | write_flags, 0666); if (krfd == -1) xerror(NO, NO, YES, "%s", genkeyf); -_xts2genkey: if (write(krfd, pblk, TF_FROM_BITS(TFC_KEY_BITS)) == -1) xerror(NO, NO, YES, "%s", genkeyf); +_xts2genkey: if (xwrite(krfd, pblk, TF_FROM_BITS(TFC_KEY_BITS)) == NOSIZE) xerror(NO, NO, YES, "%s", genkeyf); if (do_fsync && fsync(krfd) == -1) xerror(NO, NO, YES, "%s", genkeyf); if (verbose && xtskeyset == NO) { tfc_esay("%s: password hashing done", progname); @@ -896,7 +896,7 @@ _xts2genkey: if (write(krfd, pblk, TF_FROM_BITS(TFC_KEY_BITS)) == -1) xerror(NO, case TFC_CTR_SHOW: switch (do_outfmt) { case TFC_OUTFMT_B64: tfc_printbase64(stderr, ctr, ctrsz, YES); break; - case TFC_OUTFMT_RAW: write(2, ctr, ctrsz); break; + case TFC_OUTFMT_RAW: xwrite(2, ctr, ctrsz); break; case TFC_OUTFMT_HEX: mehexdump(ctr, ctrsz, ctrsz, YES); break; } break; @@ -960,7 +960,7 @@ _plain: pblk = ctr; lio = lrem = ctrsz; ldone = 0; -_ctrwagain: lio = write(dfd, pblk, lrem); +_ctrwagain: lio = xwrite(dfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else xerror(NO, NO, NO, "%s", dstfname); if (do_fsync && fsync(dfd) == -1) xerror(NO, NO, NO, "%s", dstfname); @@ -981,7 +981,7 @@ _ctrwagain: lio = write(dfd, pblk, lrem); ldone = 0; lrem = lblock = blk_len_adj(maxlen, total_processed_src, blksize); if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd); -_ragain: lio = read(sfd, pblk, lrem); +_ragain: lio = xread(sfd, pblk, lrem); if (lio == 0) do_stop = TFC_STOP_BEGAN; if (lio != NOSIZE) ldone += lio; else { @@ -1047,7 +1047,7 @@ _ragain: lio = read(sfd, pblk, lrem); pblk = dstblk; lrem = ldone; ldone = 0; -_wagain: lio = write(dfd, pblk, lrem); +_wagain: lio = xwrite(dfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else xerror(NO, NO, NO, "%s", dstfname); if (do_fsync && fsync(dfd) == -1) xerror(NO, NO, NO, "%s", dstfname); @@ -1071,7 +1071,7 @@ _nowrite: total_processed_dst += ldone; ldone = 0; lrem = lblock = TF_FROM_BITS(macbits); if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd); -_macragain: lio = read(sfd, pblk, lrem); +_macragain: lio = xread(sfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else { if (errno != EIO && catch_all_errors != YES) @@ -1102,7 +1102,7 @@ _macragain: lio = read(sfd, pblk, lrem); if (!strcmp(do_mac_file, "-")) mfd = 0; else mfd = open(do_mac_file, O_RDONLY | O_LARGEFILE); if (mfd == -1) xerror(YES, NO, NO, "%s", do_mac_file); - lio = ldone = read(mfd, tmpdata, sizeof(tmpdata)); + lio = ldone = xread(mfd, tmpdata, sizeof(tmpdata)); if (lio == NOSIZE) xerror(NO, NO, YES, "%s", do_mac_file); if (!memcmp(tmpdata, TFC_ASCII_TFC_MAC_FOURCC, TFC_ASCII_TFC_MAC_FOURCC_LEN)) { memmove(tmpdata, tmpdata+TFC_ASCII_TFC_MAC_FOURCC_LEN, @@ -1167,7 +1167,7 @@ _shortmac: memset(macvrfy, 0, sizeof(macvrfy)); pblk = tmpdata; lio = lrem = TF_FROM_BITS(macbits); ldone = 0; -_macwagain: lio = write(dfd, pblk, lrem); +_macwagain: lio = xwrite(dfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else xerror(NO, NO, NO, "%s", dstfname); if (do_fsync && fsync(dfd) == -1) xerror(NO, NO, NO, "%s", dstfname); @@ -1195,9 +1195,9 @@ _macwagain: lio = write(dfd, pblk, lrem); tmpdata[lrem] = '\n'; lrem++; } - lio = write(mfd, tmpdata, lrem); + lio = xwrite(mfd, tmpdata, lrem); } - else lio = write(mfd, tmpdata, TF_FROM_BITS(macbits)); + else lio = xwrite(mfd, tmpdata, TF_FROM_BITS(macbits)); if (lio == NOSIZE) xerror(NO, NO, YES, "%s", do_mac_file); if (do_fsync && fsync(mfd) == -1) xerror(NO, NO, YES, "%s", do_mac_file); xclose(mfd); diff --git a/tfcrypt.h b/tfcrypt.h index 5c68552..19aa726 100644 --- a/tfcrypt.h +++ b/tfcrypt.h @@ -157,6 +157,9 @@ extern tfc_useconds status_timer, bench_timer; extern tfc_useconds current_time, delta_time; extern struct getpasswd_state getps; +size_t xread(int fd, void *data, size_t szdata); +size_t xwrite(int fd, const void *data, size_t szdata); + void xerror(tfc_yesno noexit, tfc_yesno noerrno, tfc_yesno nostats, const char *fmt, ...); void xexit(int status); void usage(void); -- 2.31.1