in src/hashreader.c [32:96]
sparkey_returncode sparkey_hash_open(sparkey_hashreader **reader_ref, const char *hash_filename, const char *log_filename) {
RETHROW(correct_endian_platform());
sparkey_returncode returncode;
sparkey_hashreader *reader = malloc(sizeof(sparkey_hashreader));
if (reader == NULL) {
return SPARKEY_INTERNAL_ERROR;
}
reader->open_status = 0;
TRY(sparkey_load_hashheader(&reader->header, hash_filename), free_reader);
TRY(sparkey_logreader_open_noalloc(&reader->log, log_filename), free_reader);
if (reader->header.file_identifier != reader->log.header.file_identifier) {
returncode = SPARKEY_FILE_IDENTIFIER_MISMATCH;
goto close_reader;
}
if (reader->header.data_end > reader->log.header.data_end) {
returncode = SPARKEY_HASH_HEADER_CORRUPT;
goto close_reader;
}
if (reader->header.max_key_len > reader->log.header.max_key_len) {
returncode = SPARKEY_HASH_HEADER_CORRUPT;
goto close_reader;
}
if (reader->header.max_value_len > reader->log.header.max_value_len) {
returncode = SPARKEY_HASH_HEADER_CORRUPT;
goto close_reader;
}
reader->fd = open(hash_filename, O_RDONLY);
if (reader->fd < 0) {
int e = errno;
returncode = sparkey_open_returncode(e);
goto close_reader;
}
reader->data_len = reader->header.header_size + reader->header.hash_capacity * (reader->header.hash_size + reader->header.address_size);
struct stat s;
stat(hash_filename, &s);
if (reader->data_len > (uint64_t) s.st_size) {
returncode = SPARKEY_HASH_TOO_SMALL;
goto close_reader;
}
reader->data = mmap(NULL, reader->data_len, PROT_READ, MAP_SHARED, reader->fd, 0);
if (reader->data == MAP_FAILED) {
returncode = SPARKEY_MMAP_FAILED;
goto close_reader;
}
*reader_ref = reader;
reader->open_status = MAGIC_VALUE_HASHREADER;
return SPARKEY_SUCCESS;
close_reader:
sparkey_hash_close(&reader);
return returncode;
free_reader:
free(reader);
return returncode;
}