uint32_t version_;
uint32_t size_;
uint32_t reserved_;
-};
+} _packed;
template <typename Target_>
class Offset {
bool IsNull() const {
return offset_ == 0;
}
-};
+} _packed;
struct Block {
Cytore::Offset<void> reserved_;
-};
+} _packed;
template <typename Type_>
static _finline Type_ Round(Type_ value, Type_ size) {
bool Truncate_(size_t capacity) {
capacity = Round(capacity, Block_);
+
int error(ftruncate(file_, capacity));
- _assert(error == 0);
+ if (error != 0)
+ return false;
+
Map_(capacity);
return true;
}
return blocks_.size() * Block_;
}
- void Open(const char *path) {
+ void Open(const char *path) { open:
_assert(file_ == -1);
file_ = open(path, O_RDWR | O_CREAT | O_EXLOCK, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
_assert(file_ != -1);
size_t size(stat.st_size);
if (size == 0) {
- _assert(Truncate_(core));
+ if (!Truncate_(core)) {
+ unlink(path);
+ _assert(false);
+ }
+
Header_().magic_ = Magic;
Size_() = core;
+ } else if (size < core) {
+ close(file_);
+ file_ = -1;
+ unlink(path);
+ goto open;
} else {
- _assert(size >= core);
// XXX: this involves an unneccessary call to ftruncate()
_assert(Truncate_(size));
_assert(Header_().magic_ == Magic);