aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/ethereum/ethash/src/libethash/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/ethereum/ethash/src/libethash/io.c')
-rw-r--r--vendor/github.com/ethereum/ethash/src/libethash/io.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/vendor/github.com/ethereum/ethash/src/libethash/io.c b/vendor/github.com/ethereum/ethash/src/libethash/io.c
new file mode 100644
index 000000000..f4db477c2
--- /dev/null
+++ b/vendor/github.com/ethereum/ethash/src/libethash/io.c
@@ -0,0 +1,119 @@
+/*
+ This file is part of ethash.
+
+ ethash is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ ethash is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ethash. If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file io.c
+ * @author Lefteris Karapetsas <lefteris@ethdev.com>
+ * @date 2015
+ */
+#include "io.h"
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+enum ethash_io_rc ethash_io_prepare(
+ char const* dirname,
+ ethash_h256_t const seedhash,
+ FILE** output_file,
+ uint64_t file_size,
+ bool force_create
+)
+{
+ char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE];
+ enum ethash_io_rc ret = ETHASH_IO_FAIL;
+ // reset errno before io calls
+ errno = 0;
+
+ // assert directory exists
+ if (!ethash_mkdir(dirname)) {
+ ETHASH_CRITICAL("Could not create the ethash directory");
+ goto end;
+ }
+
+ ethash_io_mutable_name(ETHASH_REVISION, &seedhash, mutable_name);
+ char* tmpfile = ethash_io_create_filename(dirname, mutable_name, strlen(mutable_name));
+ if (!tmpfile) {
+ ETHASH_CRITICAL("Could not create the full DAG pathname");
+ goto end;
+ }
+
+ FILE *f;
+ if (!force_create) {
+ // try to open the file
+ f = ethash_fopen(tmpfile, "rb+");
+ if (f) {
+ size_t found_size;
+ if (!ethash_file_size(f, &found_size)) {
+ fclose(f);
+ ETHASH_CRITICAL("Could not query size of DAG file: \"%s\"", tmpfile);
+ goto free_memo;
+ }
+ if (file_size != found_size - ETHASH_DAG_MAGIC_NUM_SIZE) {
+ fclose(f);
+ ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
+ goto free_memo;
+ }
+ // compare the magic number, no need to care about endianess since it's local
+ uint64_t magic_num;
+ if (fread(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) {
+ // I/O error
+ fclose(f);
+ ETHASH_CRITICAL("Could not read from DAG file: \"%s\"", tmpfile);
+ ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
+ goto free_memo;
+ }
+ if (magic_num != ETHASH_DAG_MAGIC_NUM) {
+ fclose(f);
+ ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
+ goto free_memo;
+ }
+ ret = ETHASH_IO_MEMO_MATCH;
+ goto set_file;
+ }
+ }
+
+ // file does not exist, will need to be created
+ f = ethash_fopen(tmpfile, "wb+");
+ if (!f) {
+ ETHASH_CRITICAL("Could not create DAG file: \"%s\"", tmpfile);
+ goto free_memo;
+ }
+ // make sure it's of the proper size
+ if (fseek(f, (long int)(file_size + ETHASH_DAG_MAGIC_NUM_SIZE - 1), SEEK_SET) != 0) {
+ fclose(f);
+ ETHASH_CRITICAL("Could not seek to the end of DAG file: \"%s\". Insufficient space?", tmpfile);
+ goto free_memo;
+ }
+ if (fputc('\n', f) == EOF) {
+ fclose(f);
+ ETHASH_CRITICAL("Could not write in the end of DAG file: \"%s\". Insufficient space?", tmpfile);
+ goto free_memo;
+ }
+ if (fflush(f) != 0) {
+ fclose(f);
+ ETHASH_CRITICAL("Could not flush at end of DAG file: \"%s\". Insufficient space?", tmpfile);
+ goto free_memo;
+ }
+ ret = ETHASH_IO_MEMO_MISMATCH;
+ goto set_file;
+
+ ret = ETHASH_IO_MEMO_MATCH;
+set_file:
+ *output_file = f;
+free_memo:
+ free(tmpfile);
+end:
+ return ret;
+}