Fabcoin Core  0.16.2
P2P Digital Currency
io.c
Go to the documentation of this file.
1 /*
2  This file is part of ethash.
3 
4  ethash is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  ethash is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with ethash. If not, see <http://www.gnu.org/licenses/>.
16 */
21 #include "io.h"
22 #include <string.h>
23 #include <stdio.h>
24 #include <errno.h>
25 
27  char const* dirname,
28  ethash_h256_t const seedhash,
29  FILE** output_file,
30  uint64_t file_size,
31  bool force_create
32 )
33 {
34  char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE];
35  enum ethash_io_rc ret = ETHASH_IO_FAIL;
36  // reset errno before io calls
37  errno = 0;
38 
39  // assert directory exists
40  if (!ethash_mkdir(dirname)) {
41  ETHASH_CRITICAL("Could not create the ethash directory");
42  goto end;
43  }
44 
45  ethash_io_mutable_name(ETHASH_REVISION, &seedhash, mutable_name);
46  char* tmpfile = ethash_io_create_filename(dirname, mutable_name, strlen(mutable_name));
47  if (!tmpfile) {
48  ETHASH_CRITICAL("Could not create the full DAG pathname");
49  goto end;
50  }
51 
52  FILE *f;
53  if (!force_create) {
54  // try to open the file
55  f = ethash_fopen(tmpfile, "rb+");
56  if (f) {
57  size_t found_size;
58  if (!ethash_file_size(f, &found_size)) {
59  fclose(f);
60  ETHASH_CRITICAL("Could not query size of DAG file: \"%s\"", tmpfile);
61  goto free_memo;
62  }
63  if (file_size != found_size - ETHASH_DAG_MAGIC_NUM_SIZE) {
64  fclose(f);
66  goto free_memo;
67  }
68  // compare the magic number, no need to care about endianess since it's local
69  uint64_t magic_num;
70  if (fread(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) {
71  // I/O error
72  fclose(f);
73  ETHASH_CRITICAL("Could not read from DAG file: \"%s\"", tmpfile);
75  goto free_memo;
76  }
77  if (magic_num != ETHASH_DAG_MAGIC_NUM) {
78  fclose(f);
80  goto free_memo;
81  }
83  goto set_file;
84  }
85  }
86 
87  // file does not exist, will need to be created
88  f = ethash_fopen(tmpfile, "wb+");
89  if (!f) {
90  ETHASH_CRITICAL("Could not create DAG file: \"%s\"", tmpfile);
91  goto free_memo;
92  }
93  // make sure it's of the proper size
94  if (fseek(f, (long int)(file_size + ETHASH_DAG_MAGIC_NUM_SIZE - 1), SEEK_SET) != 0) {
95  fclose(f);
96  ETHASH_CRITICAL("Could not seek to the end of DAG file: \"%s\". Insufficient space?", tmpfile);
97  goto free_memo;
98  }
99  if (fputc('\n', f) == EOF) {
100  fclose(f);
101  ETHASH_CRITICAL("Could not write in the end of DAG file: \"%s\". Insufficient space?", tmpfile);
102  goto free_memo;
103  }
104  if (fflush(f) != 0) {
105  fclose(f);
106  ETHASH_CRITICAL("Could not flush at end of DAG file: \"%s\". Insufficient space?", tmpfile);
107  goto free_memo;
108  }
110  goto set_file;
111 
112  ret = ETHASH_IO_MEMO_MATCH;
113 set_file:
114  *output_file = f;
115 free_memo:
116  free(tmpfile);
117 end:
118  return ret;
119 }
ethash_io_rc
Possible return values of.
Definition: io.h:44
DAG with revision/hash match, but file size was wrong.
Definition: io.h:46
#define ETHASH_CRITICAL(...)
Logs a critical error in important parts of ethash.
Definition: io.h:71
char * ethash_io_create_filename(char const *dirname, char const *filename, size_t filename_length)
Create the filename for the DAG.
Definition: io_posix.c:53
bool ethash_file_size(FILE *f, size_t *ret_size)
Get a file&#39;s size.
Definition: io_posix.c:78
FILE * ethash_fopen(char const *file_name, char const *mode)
An fopen wrapper for no-warnings crossplatform fopen.
Definition: io_posix.c:32
DAG file existed and revision/hash matched. No need to do anything.
Definition: io.h:48
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)
Prepares io for ethash.
Definition: io.c:26
#define ETHASH_DAG_MAGIC_NUM_SIZE
Definition: ethash.h:40
Type of a seedhash/blockhash e.t.c.
Definition: ethash.h:48
#define f(x)
Definition: gost.cpp:57
The DAG file did not exist or there was revision/hash mismatch.
Definition: io.h:47
#define ETHASH_DAG_MAGIC_NUM
Definition: ethash.h:41
#define ETHASH_REVISION
Definition: ethash.h:29
#define DAG_MUTABLE_NAME_MAX_SIZE
Definition: io.h:42
bool ethash_mkdir(char const *dirname)
A cross-platform mkdir wrapper to create a directory or assert it&#39;s there.
Definition: io_posix.c:42
There has been an IO failure.
Definition: io.h:45