memcpy (resbuf, gcry_md_read (ctx->md_handle, algo),
gcry_md_get_algo_dlen (algo));
gcry_md_close (ctx->md_handle);
+ ctx->md_handle = NULL;
}
}
#include <gcrypt.h>
#include <unistd.h>
-extern "C" {
-
struct guix_hash_context
{
+ /* This copy constructor is needed in 'HashSink::currentHash()' where we
+ expect the copy of a 'Ctx' object to yield a truly different context. */
+ guix_hash_context (guix_hash_context &ref)
+ {
+ if (ref.md_handle == NULL)
+ md_handle = NULL;
+ else
+ gcry_md_copy (&md_handle, ref.md_handle);
+ }
+
+ /* Make sure 'md_handle' is always initialized. */
+ guix_hash_context (): md_handle (NULL) { };
+
gcry_md_hd_t md_handle;
};
+extern "C" {
extern void guix_hash_init (struct guix_hash_context *ctx, int algo);
extern void guix_hash_update (struct guix_hash_context *ctx, const void *buffer,
size_t len);
extern void guix_hash_final (void *resbuf, struct guix_hash_context *ctx,
int algo);
-
}
# Substitutions.
sed -i "$top_srcdir/nix/libstore/gc.cc" \
-e 's|/nix/find-runtime-roots\.pl|/guix/list-runtime-roots|g'
+
+# Our 'guix_hash_context' structure has a copy constructor, specifically to
+# handle the use case in 'HashSink::currentHash()' where the copy of the
+# context is expected to truly copy the underlying hash context. The copy
+# constructor cannot be used in 'Ctx' if that's a union, so turn it into a
+# structure (we can afford to two wasted words.)
+sed -i "$top_srcdir/nix/libutil/hash".{cc,hh} \
+ -e 's|union Ctx|struct Ctx|g'