static int file_seek(lua_State *T) { static const int mode[] = { SEEK_SET, SEEK_CUR, SEEK_END }; static const char *const modenames[] = { "set", "cur", "end", NULL }; struct file *f; int op; lua_Number offset; luaL_checktype(T, 1, LUA_TUSERDATA); op = luaL_checkoption(T, 2, "cur", modenames); offset = luaL_optnumber(T, 3, 0.); f = lua_touserdata(T, 1); f->seek.offset = (off_t)offset; luaL_argcheck(T, (lua_Number)f->seek.offset == offset, 3, "not an integer in proper range"); if (f->fd < 0) return io_closed(T); if (f->T != NULL) return io_busy(T); /* flush input buffer */ lem_inputbuf_init(&f->buf); f->T = T; f->seek.whence = mode[op]; lem_async_do(&f->a, file_seek_work, file_seek_reap); lua_settop(T, 1); return lua_yield(T, 1); }
static struct file * file_new(lua_State *T, int fd, int mt) { struct file *f; /* create userdata and set the metatable */ f = lua_newuserdata(T, sizeof(struct file)); lua_pushvalue(T, mt); lua_setmetatable(T, -2); /* initialize userdata */ f->T = NULL; f->fd = fd; lem_inputbuf_init(&f->buf); return f; }
static struct stream * stream_new(lua_State *T, int fd, int mt) { /* create userdata and set the metatable */ struct stream *s = lua_newuserdata(T, sizeof(struct stream)); lua_pushvalue(T, mt); lua_setmetatable(T, -2); /* initialize userdata */ stream_watch_init(s, fd); s->open = 1; s->r.data = NULL; s->w.data = NULL; lem_inputbuf_init(&s->buf); return s; }