diff --git a/STYLE b/STYLE index 1200c961..7b9e82a4 100644 --- a/STYLE +++ b/STYLE @@ -97,6 +97,10 @@ is preferred over goto done; at the start of a function. +Don't check for failures in an error-handling path if they will not affect +behaviour. In particular, if we're already in an unrecoverable state, don't +let a callback's return value determine control flow. + Headers should be included in the following groups, with a blank line after each (non-empty) group: 1. , with first followed by others alphabetically. diff --git a/libcperciva/alg/sha256.c b/libcperciva/alg/sha256.c index 1321f1f0..67ba3f9a 100644 --- a/libcperciva/alg/sha256.c +++ b/libcperciva/alg/sha256.c @@ -12,7 +12,7 @@ #include "sha256.h" -#if defined(CPUSUPPORT_X86_SHANI) && defined(CPUSUPPORT_X86_SSSE3) || \ +#if (defined(CPUSUPPORT_X86_SHANI) && defined(CPUSUPPORT_X86_SSSE3)) || \ defined(CPUSUPPORT_X86_SSE2) || \ defined(CPUSUPPORT_ARM_SHA256) #define HWACCEL @@ -197,32 +197,33 @@ hwaccel_init(void) #endif /* HWACCEL */ /* Elementary functions used by SHA256 */ -#define Ch(x, y, z) ((x & (y ^ z)) ^ z) -#define Maj(x, y, z) ((x & (y | z)) | (y & z)) -#define SHR(x, n) (x >> n) -#define ROTR(x, n) ((x >> n) | (x << (32 - n))) -#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) -#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) -#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) -#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) +#define Ch(x, y, z) (((x) & ((y) ^ (z))) ^ (z)) +#define Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z))) +#define SHR(x, n) ((x) >> (n)) +#define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) +#define S0(x) (ROTR((x), 2) ^ ROTR((x), 13) ^ ROTR((x), 22)) +#define S1(x) (ROTR((x), 6) ^ ROTR((x), 11) ^ ROTR((x), 25)) +#define s0(x) (ROTR((x), 7) ^ ROTR((x), 18) ^ SHR((x), 3)) +#define s1(x) (ROTR((x), 17) ^ ROTR((x), 19) ^ SHR((x), 10)) /* SHA256 round function */ -#define RND(a, b, c, d, e, f, g, h, k) \ - h += S1(e) + Ch(e, f, g) + k; \ - d += h; \ - h += S0(a) + Maj(a, b, c) +#define RND(a, b, c, d, e, f, g, h, k) do { \ + (h) += S1((e)) + Ch((e), (f), (g)) + (k); \ + (d) += (h); \ + (h) += S0((a)) + Maj((a), (b), (c)); \ +} while (0) /* Adjusted round function for rotating state */ #define RNDr(S, W, i, ii) \ - RND(S[(64 - i) % 8], S[(65 - i) % 8], \ - S[(66 - i) % 8], S[(67 - i) % 8], \ - S[(68 - i) % 8], S[(69 - i) % 8], \ - S[(70 - i) % 8], S[(71 - i) % 8], \ - W[i + ii] + Krnd[i + ii]) + RND((S)[(64 - (i)) % 8], (S)[(65 - (i)) % 8], \ + (S)[(66 - (i)) % 8], (S)[(67 - (i)) % 8], \ + (S)[(68 - (i)) % 8], (S)[(69 - (i)) % 8], \ + (S)[(70 - (i)) % 8], (S)[(71 - (i)) % 8], \ + (W)[(i) + (ii)] + Krnd[(i) + (ii)]) /* Message schedule computation */ #define MSCH(W, ii, i) \ - W[i + ii + 16] = s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii] + (W)[(i) + (ii) + 16] = s1((W)[(i) + (ii) + 14]) + (W)[(i) + (ii) + 9] + s0((W)[(i) + (ii) + 1]) + (W)[(i) + (ii)] /* * SHA256 block compression function. The 256-bit state is transformed via diff --git a/libcperciva/alg/sha256_arm.c b/libcperciva/alg/sha256_arm.c index 96223f4d..fd2d28f9 100644 --- a/libcperciva/alg/sha256_arm.c +++ b/libcperciva/alg/sha256_arm.c @@ -8,9 +8,7 @@ #include #include -#ifdef __ARM_NEON #include -#endif #include "sha256_arm.h" @@ -38,15 +36,15 @@ static const uint32_t Krnd[64] = { #define RND4(S, M, Kp) do { \ uint32x4_t S0_step; \ uint32x4_t Wk; \ - S0_step = S[0]; \ - Wk = vaddq_u32(M, vld1q_u32(Kp)); \ - S[0] = vsha256hq_u32(S[0], S[1], Wk); \ - S[1] = vsha256h2q_u32(S[1], S0_step, Wk); \ + S0_step = (S)[0]; \ + Wk = vaddq_u32((M), vld1q_u32(Kp)); \ + (S)[0] = vsha256hq_u32((S)[0], (S)[1], Wk); \ + (S)[1] = vsha256h2q_u32((S)[1], S0_step, Wk); \ } while (0) /* Message schedule computation */ #define MSG4(X0, X1, X2, X3) \ - X0 = vsha256su1q_u32(vsha256su0q_u32(X0, X1), X2, X3) + (X0) = vsha256su1q_u32(vsha256su0q_u32((X0), (X1)), (X2), (X3)) /** * SHA256_Transform_arm(state, block): diff --git a/libcperciva/alg/sha256_shani.c b/libcperciva/alg/sha256_shani.c index 7f97319a..47151581 100644 --- a/libcperciva/alg/sha256_shani.c +++ b/libcperciva/alg/sha256_shani.c @@ -38,7 +38,8 @@ be32dec_128(const uint8_t * src) /* Convert an unsigned 32-bit immediate into a signed value. */ #define I32(a) ((UINT32_C(a) >= UINT32_C(0x80000000)) ? \ - -(int32_t)(UINT32_C(0xffffffff) - UINT32_C(a)) - 1 : (int32_t)INT32_C(a)) + -(int32_t)(UINT32_C(0xffffffff) - UINT32_C(a)) - 1 : \ + (int32_t)INT32_C(a)) /* Load four unsigned 32-bit immediates into a vector register. */ #define IMM4(a, b, c, d) _mm_set_epi32(I32(a), I32(b), I32(c), I32(d)) @@ -48,29 +49,29 @@ be32dec_128(const uint8_t * src) __m128i M; \ \ /* Add the next four words of message schedule and round constants. */ \ - M = _mm_add_epi32(W, IMM4(K3, K2, K1, K0)); \ + M = _mm_add_epi32((W), IMM4(K3, K2, K1, K0)); \ \ /* Perform two rounds of SHA256, using the low two words in M. */ \ - S[1] = _mm_sha256rnds2_epu32(S[1], S[0], M); \ + (S)[1] = _mm_sha256rnds2_epu32((S)[1], (S)[0], M); \ \ /* Shift the two words of M down and perform the next two rounds. */ \ M = _mm_srli_si128(M, 8); \ - S[0] = _mm_sha256rnds2_epu32(S[0], S[1], M); \ + (S)[0] = _mm_sha256rnds2_epu32((S)[0], (S)[1], M); \ } while (0) /* Compute the ith set of four words of message schedule. */ #define MSG4(W, i) do { \ - W[(i + 0) % 4] = _mm_sha256msg1_epu32(W[(i + 0) % 4], W[(i + 1) % 4]); \ - W[(i + 0) % 4] = _mm_add_epi32(W[(i + 0) % 4], \ - _mm_alignr_epi8(W[(i + 3) % 4], W[(i + 2) % 4], 4)); \ - W[(i + 0) % 4] = _mm_sha256msg2_epu32(W[(i + 0) % 4], W[(i + 3) % 4]); \ + (W)[((i) + 0) % 4] = _mm_sha256msg1_epu32((W)[((i) + 0) % 4], (W)[((i) + 1) % 4]); \ + (W)[((i) + 0) % 4] = _mm_add_epi32((W)[((i) + 0) % 4], \ + _mm_alignr_epi8((W)[((i) + 3) % 4], (W)[((i) + 2) % 4], 4)); \ + (W)[((i) + 0) % 4] = _mm_sha256msg2_epu32((W)[((i) + 0) % 4], (W)[((i) + 3) % 4]); \ } while (0) /* Perform 4 rounds of SHA256 and generate more message schedule if needed. */ #define RNDMSG(S, W, i, K0, K1, K2, K3) do { \ - RND4(S, W[i % 4], K0, K1, K2, K3); \ - if (i < 12) \ - MSG4(W, i + 4); \ + RND4((S), (W)[(i) % 4], K0, K1, K2, K3); \ + if ((i) < 12) \ + MSG4((W), (i) + 4); \ } while (0) /** diff --git a/libcperciva/alg/sha256_sse2.c b/libcperciva/alg/sha256_sse2.c index 0dfc04be..4e6a0b12 100644 --- a/libcperciva/alg/sha256_sse2.c +++ b/libcperciva/alg/sha256_sse2.c @@ -51,31 +51,33 @@ static const uint32_t Krnd[64] = { }; /* Elementary functions used by SHA256 */ -#define Ch(x, y, z) ((x & (y ^ z)) ^ z) -#define Maj(x, y, z) ((x & (y | z)) | (y & z)) -#define ROTR(x, n) ((x >> n) | (x << (32 - n))) -#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) -#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define Ch(x, y, z) (((x) & ((y) ^ (z))) ^ (z)) +#define Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z))) +#define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) +#define S0(x) (ROTR((x), 2) ^ ROTR((x), 13) ^ ROTR((x), 22)) +#define S1(x) (ROTR((x), 6) ^ ROTR((x), 11) ^ ROTR((x), 25)) /* SHA256 round function */ -#define RND(a, b, c, d, e, f, g, h, k) \ - h += S1(e) + Ch(e, f, g) + k; \ - d += h; \ - h += S0(a) + Maj(a, b, c) +#define RND(a, b, c, d, e, f, g, h, k) do { \ + (h) += S1((e)) + Ch((e), (f), (g)) + (k); \ + (d) += (h); \ + (h) += S0((a)) + Maj((a), (b), (c)); \ +} while (0) /* Adjusted round function for rotating state */ #define RNDr(S, W, i, ii) \ - RND(S[(64 - i) % 8], S[(65 - i) % 8], \ - S[(66 - i) % 8], S[(67 - i) % 8], \ - S[(68 - i) % 8], S[(69 - i) % 8], \ - S[(70 - i) % 8], S[(71 - i) % 8], \ - W[i + ii] + Krnd[i + ii]) + RND((S)[(64 - (i)) % 8], (S)[(65 - (i)) % 8], \ + (S)[(66 - (i)) % 8], (S)[(67 - (i)) % 8], \ + (S)[(68 - (i)) % 8], (S)[(69 - (i)) % 8], \ + (S)[(70 - (i)) % 8], (S)[(71 - (i)) % 8], \ + (W)[(i) + (ii)] + Krnd[(i) + (ii)]) /* Message schedule computation */ -#define SHR32(x, n) (_mm_srli_epi32(x, n)) -#define ROTR32(x, n) (_mm_or_si128(SHR32(x, n), _mm_slli_epi32(x, (32-n)))) +#define SHR32(x, n) (_mm_srli_epi32((x), (n))) +#define ROTR32(x, n) (_mm_or_si128(SHR32((x), (n)), \ + _mm_slli_epi32((x), (32 - (n))))) #define s0_128(x) _mm_xor_si128(_mm_xor_si128( \ - ROTR32(x, 7), ROTR32(x, 18)), SHR32(x, 3)) + ROTR32((x), 7), ROTR32((x), 18)), SHR32((x), 3)) static inline __m128i s1_128_high(__m128i a) diff --git a/libcperciva/cpusupport/Build/cpusupport-ARM-AES.c b/libcperciva/cpusupport/Build/cpusupport-ARM-AES.c index b52c44c6..9d19ec40 100644 --- a/libcperciva/cpusupport/Build/cpusupport-ARM-AES.c +++ b/libcperciva/cpusupport/Build/cpusupport-ARM-AES.c @@ -1,8 +1,6 @@ #include -#ifdef __ARM_NEON #include -#endif int main(void) @@ -20,6 +18,7 @@ main(void) /* Check _u32: some compilers only support the _u8 variant. */ lanes = vdupq_laneq_u32(lanes, 0); + (void)lanes; /* UNUSED */ /* Success! */ return (0); diff --git a/libcperciva/cpusupport/Build/cpusupport-ARM-SHA256.c b/libcperciva/cpusupport/Build/cpusupport-ARM-SHA256.c index 7a04d87b..3183118c 100644 --- a/libcperciva/cpusupport/Build/cpusupport-ARM-SHA256.c +++ b/libcperciva/cpusupport/Build/cpusupport-ARM-SHA256.c @@ -1,6 +1,4 @@ -#ifdef __ARM_NEON #include -#endif int main(void) diff --git a/libcperciva/crypto/crypto_aes_aesni.c b/libcperciva/crypto/crypto_aes_aesni.c index f69db9a7..b6559a05 100644 --- a/libcperciva/crypto/crypto_aes_aesni.c +++ b/libcperciva/crypto/crypto_aes_aesni.c @@ -23,13 +23,13 @@ struct crypto_aes_key_aesni { /* Compute an AES-128 round key. */ #define MKRKEY128(rkeys, i, rcon) do { \ - __m128i _s = rkeys[i - 1]; \ - __m128i _t = rkeys[i - 1]; \ + __m128i _s = (rkeys)[(i) - 1]; \ + __m128i _t = (rkeys)[(i) - 1]; \ _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4)); \ _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8)); \ - _t = _mm_aeskeygenassist_si128(_t, rcon); \ + _t = _mm_aeskeygenassist_si128(_t, (rcon)); \ _t = _mm_shuffle_epi32(_t, 0xff); \ - rkeys[i] = _mm_xor_si128(_s, _t); \ + (rkeys)[(i)] = _mm_xor_si128(_s, _t); \ } while (0) /** @@ -79,13 +79,13 @@ crypto_aes_key_expand_128_aesni(const uint8_t key_unexpanded[16], /* Compute an AES-256 round key. */ #define MKRKEY256(rkeys, i, shuffle, rcon) do { \ - __m128i _s = rkeys[i - 2]; \ - __m128i _t = rkeys[i - 1]; \ + __m128i _s = (rkeys)[(i) - 2]; \ + __m128i _t = (rkeys)[(i) - 1]; \ _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4)); \ _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8)); \ - _t = _mm_aeskeygenassist_si128(_t, rcon); \ - _t = _mm_shuffle_epi32(_t, shuffle); \ - rkeys[i] = _mm_xor_si128(_s, _t); \ + _t = _mm_aeskeygenassist_si128(_t, (rcon)); \ + _t = _mm_shuffle_epi32(_t, (shuffle)); \ + (rkeys)[(i)] = _mm_xor_si128(_s, _t); \ } while (0) /** diff --git a/libcperciva/crypto/crypto_aes_arm.c b/libcperciva/crypto/crypto_aes_arm.c index 38d27c70..92603c8a 100644 --- a/libcperciva/crypto/crypto_aes_arm.c +++ b/libcperciva/crypto/crypto_aes_arm.c @@ -7,9 +7,7 @@ #include #include -#ifdef __ARM_NEON #include -#endif #include "align_ptr.h" #include "insecure_memzero.h" @@ -30,7 +28,7 @@ struct crypto_aes_key_arm { * vdupq_laneq_u32(), except that accepts (and returns) uint8x16_t. */ #define vdupq_laneq_u32_u8(a, lane) \ - vreinterpretq_u8_u32(vdupq_laneq_u32(vreinterpretq_u32_u8(a), lane)) + vreinterpretq_u8_u32(vdupq_laneq_u32(vreinterpretq_u32_u8(a), (lane))) /** * vshlq_n_u128(a, n): @@ -45,7 +43,7 @@ struct crypto_aes_key_arm { * intrinsics; all of the built-in shift instructions operate on multiple * values (such as a pair of 64-bit values). */ -#define vshlq_n_u128(a, n) vextq_u8(vdupq_n_u8(0), a, 16 - n) +#define vshlq_n_u128(a, n) vextq_u8(vdupq_n_u8(0), (a), 16 - (n)) /** * SubWord_duplicate(a): @@ -101,12 +99,12 @@ SubWord_RotWord_XOR_duplicate(uint8x16_t a, const uint32_t rcon) /* Compute an AES-128 round key. */ #define MKRKEY128(rkeys, i, rcon) do { \ - uint8x16_t _s = rkeys[i - 1]; \ - uint8x16_t _t = rkeys[i - 1]; \ + uint8x16_t _s = (rkeys)[(i) - 1]; \ + uint8x16_t _t = (rkeys)[(i) - 1]; \ _s = veorq_u8(_s, vshlq_n_u128(_s, 4)); \ _s = veorq_u8(_s, vshlq_n_u128(_s, 8)); \ - _t = SubWord_RotWord_XOR_duplicate(_t, rcon); \ - rkeys[i] = veorq_u8(_s, _t); \ + _t = SubWord_RotWord_XOR_duplicate(_t, (rcon)); \ + (rkeys)[(i)] = veorq_u8(_s, _t); \ } while (0) /** @@ -144,14 +142,14 @@ crypto_aes_key_expand_128_arm(const uint8_t key_unexpanded[16], /* Compute an AES-256 round key. */ #define MKRKEY256(rkeys, i, rcon) do { \ - uint8x16_t _s = rkeys[i - 2]; \ - uint8x16_t _t = rkeys[i - 1]; \ + uint8x16_t _s = (rkeys)[(i) - 2]; \ + uint8x16_t _t = (rkeys)[(i) - 1]; \ _s = veorq_u8(_s, vshlq_n_u128(_s, 4)); \ _s = veorq_u8(_s, vshlq_n_u128(_s, 8)); \ - _t = (i % 2 == 1) ? \ + _t = ((i) % 2 == 1) ? \ SubWord_duplicate(_t) : \ - SubWord_RotWord_XOR_duplicate(_t, rcon); \ - rkeys[i] = veorq_u8(_s, _t); \ + SubWord_RotWord_XOR_duplicate(_t, (rcon)); \ + (rkeys)[(i)] = veorq_u8(_s, _t); \ } while (0) /** diff --git a/libcperciva/crypto/crypto_aes_arm_u8.h b/libcperciva/crypto/crypto_aes_arm_u8.h index 173020bd..dcccba83 100644 --- a/libcperciva/crypto/crypto_aes_arm_u8.h +++ b/libcperciva/crypto/crypto_aes_arm_u8.h @@ -1,9 +1,7 @@ #ifndef CRYPTO_AES_ARM_U8_H_ #define CRYPTO_AES_ARM_U8_H_ -#ifdef __ARM_NEON #include -#endif /** * crypto_aes_encrypt_block_arm_u8(in, key): diff --git a/libcperciva/crypto/crypto_aesctr_arm.c b/libcperciva/crypto/crypto_aesctr_arm.c index 0b8df71f..d1fd84df 100644 --- a/libcperciva/crypto/crypto_aesctr_arm.c +++ b/libcperciva/crypto/crypto_aesctr_arm.c @@ -8,9 +8,7 @@ #include #include -#ifdef __ARM_NEON #include -#endif #include "crypto_aes.h" #include "crypto_aes_arm_u8.h" diff --git a/libcperciva/crypto/crypto_aesctr_shared.c b/libcperciva/crypto/crypto_aesctr_shared.c index 632e419c..a91d8253 100644 --- a/libcperciva/crypto/crypto_aesctr_shared.c +++ b/libcperciva/crypto/crypto_aesctr_shared.c @@ -1,3 +1,5 @@ +#include + /* * This code is shared between crypto_aesctr*.c files, and should not be * compiled as a separate translation unit. For details, see the comments in diff --git a/libcperciva/crypto/crypto_entropy.c b/libcperciva/crypto/crypto_entropy.c index 936e22ae..1922f51c 100644 --- a/libcperciva/crypto/crypto_entropy.c +++ b/libcperciva/crypto/crypto_entropy.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "cpusupport.h" @@ -55,6 +56,14 @@ update_from_rdrand(void) } #endif +/* Clear the DRBG internal state. */ +static void +crypto_entropy_atexit(void) +{ + + insecure_memzero(&drbg, sizeof(drbg)); +} + /** * instantiate(void): * Initialize the DRBG state. (Section 10.1.2.3) @@ -210,9 +219,13 @@ crypto_entropy_read(uint8_t * buf, size_t buflen) /* Instantiate if needed. */ if (instantiated == 0) { + /* Clear the internal state on exit. */ + if (atexit(crypto_entropy_atexit)) + goto err0; + /* Try to instantiate the PRNG. */ if (instantiate()) - return (-1); + goto err0; /* We have instantiated the PRNG. */ instantiated = 1; @@ -223,7 +236,7 @@ crypto_entropy_read(uint8_t * buf, size_t buflen) /* Do we need to reseed? */ if (drbg.reseed_counter > RESEED_INTERVAL) { if (reseed()) - return (-1); + goto err0; } /* How much data are we generating in this step? */ @@ -242,4 +255,8 @@ crypto_entropy_read(uint8_t * buf, size_t buflen) /* Success! */ return (0); + +err0: + /* Failure! */ + return (-1); } diff --git a/libcperciva/util/align_ptr.h b/libcperciva/util/align_ptr.h index ebe3e0f9..c87d83d9 100644 --- a/libcperciva/util/align_ptr.h +++ b/libcperciva/util/align_ptr.h @@ -13,7 +13,7 @@ * "${name}_buf". */ #define ALIGN_PTR_DECL(type, name, num, alignsize) \ - uint8_t name##_buf[num * sizeof(type) + (alignsize - 1)]; \ + uint8_t name##_buf[(num) * sizeof(type) + ((alignsize) - 1)]; \ type * name /** @@ -25,7 +25,7 @@ * relative to aligned memory. */ #define ALIGN_PTR_INIT(name, alignsize) \ - name = align_ptr(name##_buf, alignsize) + (name) = align_ptr(name##_buf, (alignsize)) /** * align_ptr(arr, alignment): diff --git a/libcperciva/util/getopt.c b/libcperciva/util/getopt.c index f0bb09d1..72476259 100644 --- a/libcperciva/util/getopt.c +++ b/libcperciva/util/getopt.c @@ -3,6 +3,8 @@ #include #include +#include "warnp.h" + #include "getopt.h" /* @@ -90,7 +92,11 @@ reset(int argc, char * const argv[]) /* Register atexit handler if we haven't done so already. */ if (!atexit_registered) { - atexit(getopt_atexit); + /* On failure, warn only; we're inside a (void) function. */ + if (atexit(getopt_atexit)) + warnp("atexit"); + + /* Don't try atexit() again. */ atexit_registered = 1; } diff --git a/libcperciva/util/getopt.h b/libcperciva/util/getopt.h index 965f0639..cac176c9 100644 --- a/libcperciva/util/getopt.h +++ b/libcperciva/util/getopt.h @@ -83,7 +83,7 @@ extern int optind, opterr, optreset; * the next option string and set optarg / optind appropriately; abort if not * properly initialized when not being called for the first time. */ -#define GETOPT(argc, argv) getopt(argc, argv) +#define GETOPT(argc, argv) getopt((argc), (argv)) /** * GETOPT_SWITCH(ch): @@ -107,13 +107,13 @@ extern int optind, opterr, optreset; * GETOPT_OPT("-x") is equivalent to "case 'x'" in a standard getopt loop * which has an optstring containing "x". */ -#define GETOPT_OPT(os) GETOPT_OPT_(os, __LINE__) -#define GETOPT_OPT_(os, ln) GETOPT_OPT__(os, ln) +#define GETOPT_OPT(os) GETOPT_OPT_((os), __LINE__) +#define GETOPT_OPT_(os, ln) GETOPT_OPT__((os), ln) #define GETOPT_OPT__(os, ln) \ case ln: \ if (getopt_initialized) \ goto getopt_skip_ ## ln; \ - getopt_register_opt(os, ln - getopt_ln_min, 0); \ + getopt_register_opt((os), (ln) - getopt_ln_min, 0); \ DO_LONGJMP; \ getopt_skip_ ## ln @@ -126,15 +126,15 @@ extern int optind, opterr, optreset; * GETOPT_OPTARG("-x") is equivalent to "case 'x'" in a standard getopt loop * which has an optstring containing "x:". */ -#define GETOPT_OPTARG(os) GETOPT_OPTARG_(os, __LINE__) -#define GETOPT_OPTARG_(os, ln) GETOPT_OPTARG__(os, ln) +#define GETOPT_OPTARG(os) GETOPT_OPTARG_((os), __LINE__) +#define GETOPT_OPTARG_(os, ln) GETOPT_OPTARG__((os), ln) #define GETOPT_OPTARG__(os, ln) \ case ln: \ if (getopt_initialized) { \ assert(optarg != NULL); \ goto getopt_skip_ ## ln; \ } \ - getopt_register_opt(os, ln - getopt_ln_min, 1); \ + getopt_register_opt((os), (ln) - getopt_ln_min, 1); \ DO_LONGJMP; \ getopt_skip_ ## ln @@ -153,7 +153,7 @@ extern int optind, opterr, optreset; case ln: \ if (getopt_initialized) \ goto getopt_skip_ ## ln; \ - getopt_register_missing(ln - getopt_ln_min); \ + getopt_register_missing((ln) - getopt_ln_min); \ DO_LONGJMP; \ getopt_skip_ ## ln @@ -179,7 +179,7 @@ extern int optind, opterr, optreset; if (getopt_initialized) \ goto getopt_skip_ ## ln; \ if (!getopt_default_missing) { \ - getopt_setrange(ln - getopt_ln_min); \ + getopt_setrange((ln) - getopt_ln_min); \ getopt_default_missing = 1; \ } \ DO_LONGJMP; \ diff --git a/libcperciva/util/humansize.c b/libcperciva/util/humansize.c index 32160b08..750e019e 100644 --- a/libcperciva/util/humansize.c +++ b/libcperciva/util/humansize.c @@ -1,4 +1,5 @@ #include +#include #include "asprintf.h" #include "warnp.h" diff --git a/libcperciva/util/parsenum.h b/libcperciva/util/parsenum.h index d8406c9b..ab21e09a 100644 --- a/libcperciva/util/parsenum.h +++ b/libcperciva/util/parsenum.h @@ -54,9 +54,9 @@ _Pragma("clang diagnostic pop") * set to +/- infinity or the limits of the unsigned integer type. */ #define PARSENUM2(x, s) \ - PARSENUM_EX4(x, s, 0, 0, "PARSENUM") + PARSENUM_EX4((x), (s), 0, 0, "PARSENUM") #define PARSENUM4(x, s, min, max) \ - PARSENUM_EX6(x, s, min, max, 0, 0, "PARSENUM") + PARSENUM_EX6((x), (s), (min), (max), 0, 0, "PARSENUM") /* Magic to select which version of PARSENUM to use. */ #define PARSENUM(...) PARSENUM_(PARSENUM_COUNT(__VA_ARGS__))(__VA_ARGS__) diff --git a/libcperciva/util/readpass.c b/libcperciva/util/readpass.c index 3683aa1f..322f7f4a 100644 --- a/libcperciva/util/readpass.c +++ b/libcperciva/util/readpass.c @@ -17,12 +17,13 @@ static const int badsigs[] = { SIGPIPE, SIGQUIT, SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU }; -#define NSIGS sizeof(badsigs)/sizeof(badsigs[0]) +#define NSIGS (sizeof(badsigs)/sizeof(badsigs[0])) /* Highest signal number we care about. */ #define MAX2(a, b) ((a) > (b) ? (a) : (b)) -#define MAX4(a, b, c, d) MAX2(MAX2(a, b), MAX2(c, d)) -#define MAX8(a, b, c, d, e, f, g, h) MAX2(MAX4(a, b, c, d), MAX4(e, f, g, h)) +#define MAX4(a, b, c, d) MAX2(MAX2((a), (b)), MAX2((c), (d))) +#define MAX8(a, b, c, d, e, f, g, h) \ + MAX2(MAX4((a), (b), (c), (d)), MAX4((e), (f), (g), (h))) #define MAXBADSIG MAX2(SIGALRM, MAX8(SIGHUP, SIGINT, SIGPIPE, SIGQUIT, \ SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU)) diff --git a/libcperciva/util/readpass_file.c b/libcperciva/util/readpass_file.c index 4379a61d..14ad1fcf 100644 --- a/libcperciva/util/readpass_file.c +++ b/libcperciva/util/readpass_file.c @@ -44,6 +44,9 @@ readpass_file(char ** passwd, const char * filename) if (fgetc(f) != EOF) { warn0("line too long, or more than 1 line in %s", filename); goto err2; + } else if (ferror(f)) { + warnp("fgetc"); + goto err2; } /* Close the file. */ diff --git a/libcperciva/util/warnp.c b/libcperciva/util/warnp.c index 04c0d0cf..4ec502cb 100644 --- a/libcperciva/util/warnp.c +++ b/libcperciva/util/warnp.c @@ -47,7 +47,11 @@ warnp_setprogname(const char * progname) /* If we haven't already done so, register our exit handler. */ if (initialized == 0) { - atexit(warnp_atexit); + /* On failure, warn only; we're inside a (void) function. */ + if (atexit(warnp_atexit)) + warnp("atexit"); + + /* Don't try atexit() again. */ initialized = 1; } }