Convert shacheck to c to aid in finding memory leaks (bash is horribly
authorJonathan Dieter <jdieter@gmail.com>
Mon, 8 Oct 2018 15:22:11 +0000 (16:22 +0100)
committerJonathan Dieter <jdieter@gmail.com>
Mon, 8 Oct 2018 15:22:11 +0000 (16:22 +0100)
leaky)

Signed-off-by: Jonathan Dieter <jdieter@gmail.com>
test/meson.build
test/shacheck.c [new file with mode: 0644]
test/shacheck.sh [deleted file]

index f7a468fa939a71645da4440fb2d43f714f71b70a..714ae3de3ac025fb0bb063519e60aa77d59f2e53 100644 (file)
@@ -3,7 +3,7 @@ subdir('lib')
 incdir = include_directories(['lib', '../src/lib', '../include'])
 empty = executable('empty', ['empty.c'] + util_sources, include_directories: incdir, dependencies: [zstd_dep, openssl_dep])
 optflag = executable('optflag', ['optflag.c'] + util_sources, include_directories: incdir, dependencies: [zstd_dep, openssl_dep])
-shacheck = find_program('shacheck.sh')
+shacheck = executable('shacheck', ['shacheck.c'] + util_sources, include_directories: incdir, dependencies: [zstd_dep, openssl_dep])
 file_path = join_paths(meson.source_root(), 'test/files')
 
 test(
diff --git a/test/shacheck.c b/test/shacheck.c
new file mode 100644 (file)
index 0000000..b65bb28
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2018 Jonathan Dieter <jdieter@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *
+ *  2. Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <zck.h>
+#include <sys/wait.h>
+#include "zck_private.h"
+#include "util.h"
+
+int main (int argc, char *argv[]) {
+    if(argc < 4) {
+        printf("Usage: %s <command> <outputfile> <expected checksum> [args]\n",
+               argv[0]);
+        exit(1);
+    }
+
+    char *cmd = argv[1];
+    char *outf = argv[2];
+    char *echecksum = argv[3];
+
+    char **args = calloc(argc-2, sizeof(void*));
+
+    args[0] = argv[1];
+    for(int i=1; i<argc-3; i++)
+        args[i] = argv[i+3];
+
+    int status;
+    pid_t child_pid;
+
+    child_pid = fork();
+    if (child_pid == -1) {
+        perror("fork failed");
+        exit(1);
+    } else if(child_pid == 0) {
+        execv(cmd, args);
+        perror("Unable to run command");
+        exit(1);
+    } else {
+        waitpid(child_pid, &status, 0);
+    }
+    if (status != 0) {
+        printf("Error running command\n");
+        exit(1);
+    }
+
+    /* Open zchunk file and check that checksum matches */
+    int in = open(outf, O_RDONLY);
+    if(in < 0) {
+        perror("");
+        printf("Unable to open %s for reading", outf);
+        exit(1);
+    }
+    /* Files must be smaller than 1MB  */
+    char data[1024*1024] = {0};
+    ssize_t len = read(in, data, 1024*1024);
+    if(len < 0) {
+        perror("");
+        printf("Unable to read from %s", outf);
+        exit(1);
+    }
+    char *cksum = get_hash(data, len, ZCK_HASH_SHA256);
+    printf("%s:\n", outf);
+    printf("Calculated checksum: (SHA-256)%s\n", cksum);
+    printf("Expected checksum: (SHA-256)%s\n", echecksum);
+    if(memcmp(cksum, echecksum, strlen(echecksum)) != 0) {
+        printf("Checksums don't match!\n");
+        exit(1);
+    }
+    free(cksum);
+    free(args);
+    return 0;
+}
diff --git a/test/shacheck.sh b/test/shacheck.sh
deleted file mode 100755 (executable)
index 0f9e92b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-CMD="$1"
-EOUTPUT="$2"
-ECHKSUM="$3"
-shift 3
-"$CMD" $@
-
-if [ "$?" -ne 0 ]; then
-    exit 1
-fi
-
-CHKSUM=$(sha256sum "$EOUTPUT" | awk '{ print $1 }')
-if [ "$CHKSUM" != "$ECHKSUM" ]; then
-    echo "Calculated checksum: $CHKSUM"
-    echo "Expected checksum: $ECHKSUM"
-    echo "Checksum doesn't match"
-    exit 1
-fi
-
-rm "$EOUTPUT" -f
-exit 0