static INLINE bool SI_init_read_only(FSFileHandle *self, FSFileHandleIVARS *ivars) { UNUSED_VAR(self); // Open. ivars->fd = open((char*)CB_Get_Ptr8(ivars->path), SI_posix_flags(ivars->flags), 0666); if (ivars->fd == -1) { ivars->fd = 0; Err_set_error(Err_new(CB_newf("Can't open '%o': %s", ivars->path, strerror(errno)))); return false; } // Derive len. ivars->len = lseek64(ivars->fd, INT64_C(0), SEEK_END); if (ivars->len == -1) { Err_set_error(Err_new(CB_newf("lseek64 on %o failed: %s", ivars->path, strerror(errno)))); return false; } else { int64_t check_val = lseek64(ivars->fd, INT64_C(0), SEEK_SET); if (check_val == -1) { Err_set_error(Err_new(CB_newf("lseek64 on %o failed: %s", ivars->path, strerror(errno)))); return false; } } // Get system page size. #if defined(_SC_PAGESIZE) ivars->page_size = sysconf(_SC_PAGESIZE); #elif defined(_SC_PAGE_SIZE) ivars->page_size = sysconf(_SC_PAGE_SIZE); #else #error "Can't determine system memory page size" #endif return true; }
FSFileHandle* FSFH_do_open(FSFileHandle *self, const CharBuf *path, uint32_t flags) { FH_do_open((FileHandle*)self, path, flags); if (!path || !CB_Get_Size(path)) { Err_set_error(Err_new(CB_newf("Missing required param 'path'"))); CFISH_DECREF(self); return NULL; } // Attempt to open file. if (flags & FH_WRITE_ONLY) { self->fd = open((char*)CB_Get_Ptr8(path), SI_posix_flags(flags), 0666); if (self->fd == -1) { self->fd = 0; Err_set_error(Err_new(CB_newf("Attempt to open '%o' failed: %s", path, strerror(errno)))); CFISH_DECREF(self); return NULL; } if (flags & FH_EXCLUSIVE) { self->len = 0; } else { // Derive length. self->len = lseek64(self->fd, I64_C(0), SEEK_END); if (self->len == -1) { Err_set_error(Err_new(CB_newf("lseek64 on %o failed: %s", self->path, strerror(errno)))); CFISH_DECREF(self); return NULL; } else { int64_t check_val = lseek64(self->fd, I64_C(0), SEEK_SET); if (check_val == -1) { Err_set_error(Err_new(CB_newf("lseek64 on %o failed: %s", self->path, strerror(errno)))); CFISH_DECREF(self); return NULL; } } } } else if (flags & FH_READ_ONLY) { if (SI_init_read_only(self)) { // On 64-bit systems, map the whole file up-front. if (IS_64_BIT && self->len) { self->buf = (char*)SI_map(self, 0, self->len); if (!self->buf) { // An error occurred during SI_map, which has set // Err_error for us already. CFISH_DECREF(self); return NULL; } } } else { CFISH_DECREF(self); return NULL; } } else { Err_set_error(Err_new(CB_newf("Must specify FH_READ_ONLY or FH_WRITE_ONLY to open '%o'", path))); CFISH_DECREF(self); return NULL; } return self; }