// For some fucking reason, libuv hasn't implemented lseek() (WHY??) // Here, a sync version is implemented (as i cannot be bothered with callbacks) #include #include #include #include #include #include #ifdef _WIN32 #include #include #define off_t LONGLONG #define _LARGEFILE_SOURCE #endif static int luafunc_seek(lua_State *ctx) { int fd = lua_tointeger(ctx, 1); off_t offset = lua_isnoneornil(ctx, 2) ? 0 : luaL_checkinteger(ctx, 2); int whence = SEEK_CUR; if (!lua_isnoneornil(ctx, 3)) { const char *swhence = luaL_checkstring(ctx, 3); if (!strcmp(swhence, "set")) { whence = SEEK_SET; } else if (!strcmp(swhence, "cur")) { whence = SEEK_CUR; } else if (!strcmp(swhence, "end")) { whence = SEEK_END; } else { luaL_typeerror(ctx, 3, "'set', 'cur' or 'end'"); } } #ifdef _WIN32 HANDLE fh; LARGE_INTEGER new_offset; fh = (HANDLE)_get_osfhandle(fd); if (fh == (HANDLE)-1) { errno = EBADF; return -1; } DWORD method; switch (whence) { case SEEK_SET: method = FILE_BEGIN; break; case SEEK_CUR: method = FILE_CURRENT; break; case SEEK_END: method = FILE_END; break; default: errno = EINVAL; return -1; } LARGE_INTEGER distance; distance.QuadPart = offset; if (!SetFilePointerEx(fh, distance, &new_offset, method)) { lua_pushnil(ctx); lua_pushstring(ctx, strerror(EINVAL)); return 2; } off_t offs = new_offset.QuadPart; #else off_t offs = lseek(fd, offset, whence); if (offs < 0) { lua_pushnil(ctx); lua_pushstring(ctx, strerror(errno)); return 2; } #endif lua_pushinteger(ctx, offs); return 1; } int luaopen_seek(lua_State *ctx) { lua_pushcfunction(ctx, luafunc_seek); return 1; }