static ERL_NIF_TERM seek_nif()

in src/couch/priv/couch_cfile/couch_cfile.c [462:510]


static ERL_NIF_TERM seek_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
#ifdef COUCH_CFILE_SUPPORTED
    handle_t* hdl;
    long result, offset;
    int whence;

    if (argc != 3
       || !get_handle(env, argv[0], &hdl)
       || !enif_is_atom(env, argv[1])
       || !enif_is_number(env, argv[2])
    ) {
     return badarg(env);
    }

    if (enif_is_identical(argv[1], ATOM_BOF)) {
        whence = SEEK_SET;
    } else if (enif_is_identical(argv[1], ATOM_EOF)) {
        whence = SEEK_END;
    } else {
        return badarg(env);
    }

    if(!enif_get_int64(env, argv[2], &offset) || offset < 0){
        return err_tup(env, EINVAL);
    }

    // ------ Critical section start ------
    READ_LOCK;
    if (hdl->fd < 0) {
        READ_UNLOCK;
        return err_tup(env, EINVAL);
    }
    result = lseek(hdl->fd, offset, whence);
    READ_UNLOCK;
    // ------ Critical section end ------

    // Follow OTP special case here: result < 0 with ernno = 0 is einval
    if(result < 0 && errno == 0) {
        return err_tup(env, EINVAL);
    }

    if(result < 0) {
        return err_tup(env, errno);
    }
    return ok_tup(env, enif_make_uint64(env, result));
#else
    return err_tup(env, EINVAL)
#endif
}