Browse Source

Move ethash_io_prepare to io.c

- Platform specific io.c files now contain only the minimum amount of
  code they can.
cl-refactor
Lefteris Karapetsas 10 years ago
parent
commit
f6d4634c75
  1. 3
      internal.c
  2. 58
      io.c
  3. 34
      io.h
  4. 58
      io_posix.c
  5. 56
      io_win32.c

3
internal.c

@ -371,12 +371,13 @@ ethash_full_t ethash_full_new(char const *dirname,
ret->file_size = (size_t)params->full_size; ret->file_size = (size_t)params->full_size;
switch (ethash_io_prepare(dirname, *seed_hash, &f, (size_t)params->full_size)) { switch (ethash_io_prepare(dirname, *seed_hash, &f, (size_t)params->full_size)) {
case ETHASH_IO_FAIL: case ETHASH_IO_FAIL:
case ETHASH_IO_MEMO_SIZE_MISMATCH:
goto fail_free_full; goto fail_free_full;
case ETHASH_IO_MEMO_MATCH: case ETHASH_IO_MEMO_MATCH:
match = true; match = true;
case ETHASH_IO_MEMO_MISMATCH: case ETHASH_IO_MEMO_MISMATCH:
ret->file = f; ret->file = f;
if ((fd = fileno(ret->file)) == -1) { if ((fd = ethash_fileno(ret->file)) == -1) {
goto fail_free_full; goto fail_free_full;
} }
ret->data = mmap( ret->data = mmap(

58
io.c

@ -48,3 +48,61 @@ free_name:
free(fullname); free(fullname);
return ret; return ret;
} }
enum ethash_io_rc ethash_io_prepare(char const *dirname,
ethash_h256_t const seedhash,
FILE **output_file,
size_t file_size)
{
char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE];
enum ethash_io_rc ret = ETHASH_IO_FAIL;
// assert directory exists
if (!ethash_mkdir(dirname)) {
goto end;
}
ethash_io_mutable_name(REVISION, &seedhash, mutable_name);
char *tmpfile = ethash_io_create_filename(dirname, mutable_name, strlen(mutable_name));
if (!tmpfile) {
goto end;
}
// try to open the file
FILE *f = ethash_fopen(tmpfile, "rb+");
if (f) {
size_t found_size;
if (!ethash_file_size(f, &found_size)) {
fclose(f);
goto free_memo;
}
if (file_size != found_size) {
fclose(f);
ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
goto free_memo;
}
} else {
// file does not exist, will need to be created
f = ethash_fopen(tmpfile, "wb+");
if (!f) {
goto free_memo;
}
// make sure it's of the proper size
if (fseek(f, file_size - 1, SEEK_SET) != 0) {
fclose(f);
goto free_memo;
}
fputc('\n', f);
fflush(f);
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;
}

34
io.h

@ -37,9 +37,10 @@ extern "C" {
#define DAG_MUTABLE_NAME_MAX_SIZE (10 + 1 + 16 + 1) #define DAG_MUTABLE_NAME_MAX_SIZE (10 + 1 + 16 + 1)
/// Possible return values of @see ethash_io_prepare /// Possible return values of @see ethash_io_prepare
enum ethash_io_rc { enum ethash_io_rc {
ETHASH_IO_FAIL = 0, ///< There has been an IO failure ETHASH_IO_FAIL = 0, ///< There has been an IO failure
ETHASH_IO_MEMO_MISMATCH, ///< The DAG file did not exist or there was revision/hash mismatch ETHASH_IO_MEMO_SIZE_MISMATCH, ///< DAG with revision/hash match, but file size was wrong.
ETHASH_IO_MEMO_MATCH, ///< DAG file existed and revision/hash matched. No need to do anything ETHASH_IO_MEMO_MISMATCH, ///< The DAG file did not exist or there was revision/hash mismatch
ETHASH_IO_MEMO_MATCH, ///< DAG file existed and revision/hash matched. No need to do anything
}; };
/** /**
@ -78,6 +79,7 @@ enum ethash_io_rc ethash_io_prepare(char const *dirname,
* @return The FILE* or NULL in failure * @return The FILE* or NULL in failure
*/ */
FILE *ethash_fopen(const char *file_name, const char *mode); FILE *ethash_fopen(const char *file_name, const char *mode);
/** /**
* An strncat wrapper for no-warnings crossplatform strncat. * An strncat wrapper for no-warnings crossplatform strncat.
* *
@ -96,6 +98,32 @@ FILE *ethash_fopen(const char *file_name, const char *mode);
*/ */
char *ethash_strncat(char *dest, size_t dest_size, const char *src, size_t count); char *ethash_strncat(char *dest, size_t dest_size, const char *src, size_t count);
/**
* A cross-platform mkdir wrapper to create a directory or assert it's there
*
* @param dirname The full path of the directory to create
* @return true if the directory was created or if it already
* existed
*/
bool ethash_mkdir(char const *dirname);
/**
* Get a file's size
*
* @param[in] f The open file stream whose size to get
* @param[out] size Pass a size_t by reference to contain the file size
* @return true in success and false if there was a failure
*/
bool ethash_file_size(FILE *f, size_t *ret_size);
/**
* Get a file descriptor number from a FILE stream
*
* @param f The file stream whose fd to get
* @return Platform specific fd handler
*/
int ethash_fileno(FILE *f);
static inline bool ethash_io_mutable_name(uint32_t revision, static inline bool ethash_io_mutable_name(uint32_t revision,
ethash_h256_t const* seed_hash, ethash_h256_t const* seed_hash,
char* output) char* output)

58
io_posix.c

@ -37,52 +37,24 @@ char *ethash_strncat(char *dest, size_t dest_size, const char *src, size_t count
return strlen(dest) + count + 1 <= dest_size ? strncat(dest, src, count) : NULL; return strlen(dest) + count + 1 <= dest_size ? strncat(dest, src, count) : NULL;
} }
enum ethash_io_rc ethash_io_prepare(char const *dirname, bool ethash_mkdir(char const *dirname)
ethash_h256_t const seedhash,
FILE **output_file,
size_t file_size)
{ {
char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE];
enum ethash_io_rc ret = ETHASH_IO_FAIL;
// assert directory exists, full owner permissions and read/search for others
int rc = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); int rc = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (rc == -1 && errno != EEXIST) { return rc != -1 || errno == EEXIST;
goto end; }
}
ethash_io_mutable_name(REVISION, &seedhash, mutable_name); int ethash_fileno(FILE *f)
char *tmpfile = ethash_io_create_filename(dirname, mutable_name, strlen(mutable_name)); {
if (!tmpfile) { return fileno(f);
goto end; }
}
// try to open the file bool ethash_file_size(FILE *f, size_t *ret_size)
FILE *f = ethash_fopen(tmpfile, "rb+"); {
if (f) { struct stat st;
// TODO: check for file size int fd;
} else { if ((fd = fileno(f)) == -1 || fstat(fd, &st) != 0) {
// file does not exist, will need to be created return false;
f = ethash_fopen(tmpfile, "wb+");
if (!f) {
goto free_memo;
}
// make sure it's of the proper size
if (fseek(f, file_size - 1, SEEK_SET) != 0) {
fclose(f);
goto free_memo;
}
fputc('\n', f);
fflush(f);
ret = ETHASH_IO_MEMO_MISMATCH;
goto set_file;
} }
*ret_size = st.st_size;
ret = ETHASH_IO_MEMO_MATCH; return true;
set_file:
*output_file = f;
free_memo:
free(tmpfile);
end:
return ret;
} }

56
io_win32.c

@ -35,50 +35,24 @@ char *ethash_strncat(char *dest, size_t dest_size, const char *src, size_t count
return strncat_s(dest, dest_size, src, count) == 0 ? dest : NULL; return strncat_s(dest, dest_size, src, count) == 0 ? dest : NULL;
} }
enum ethash_io_rc ethash_io_prepare(char const *dirname, bool ethash_mkdir(char const *dirname)
ethash_h256_t const seedhash,
FILE **output_file,
size_t file_size)
{ {
char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE];
enum ethash_io_rc ret = ETHASH_IO_FAIL;
// assert directory exists
int rc = _mkdir(dirname); int rc = _mkdir(dirname);
if (rc == -1 && errno != EEXIST) { return rc != -1 || errno == EEXIST;
goto end; }
}
ethash_io_mutable_name(REVISION, &seedhash, mutable_name); int ethash_fileno(FILE *f)
char *tmpfile = ethash_io_create_filename(dirname, mutable_name, strlen(mutable_name)); {
if (!tmpfile) { return _fileno(f);
goto end; }
}
// try to open the file bool ethash_file_size(FILE *f, size_t *ret_size)
FILE *f = ethash_fopen(tmpfile, "rb+"); {
if (!f) { struct _stat st;
// file does not exist, will need to be created int fd;
f = ethash_fopen(tmpfile, "wb+"); if ((fd = _fileno(f)) == -1 || _fstat(fd, &st) != 0) {
if (!f) { return false;
goto free_memo;
}
// make sure it's of the proper size
if (fseek(f, file_size - 1, SEEK_SET) != 0) {
fclose(f);
goto free_memo;
}
fputc('\n', f);
fflush(f);
ret = ETHASH_IO_MEMO_MISMATCH;
goto set_file;
} }
*ret_size = st.st_size;
ret = ETHASH_IO_MEMO_MATCH; return true;
set_file:
*output_file = f;
free_memo:
free(tmpfile);
end:
return ret;
} }

Loading…
Cancel
Save