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
}