Example #1
0
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;
}
Example #2
0
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;
}