Example #1
0
static int
db_exec(lua_State *T)
{
	struct db *db;
	const char *sql;
	size_t len;
	unsigned int bind;

	luaL_checktype(T, 1, LUA_TUSERDATA);
	sql = luaL_checklstring(T, 2, &len);
	bind = lua_gettop(T) > 2;
	if (bind) {
		luaL_checktype(T, 3, LUA_TTABLE);
		lua_settop(T, 3);
		lua_replace(T, 2);
	}

	db = db_unbox(T, 1);
	if (db == NULL)
		return db_closed(T);
	if (db->T != NULL)
		return db_busy(T);

	db->T = T;
	db->req.prep.sql = sql;
	db->req.prep.len = len+1;
	lem_async_do(&db->a, db_prepare_work, db_exec_prepare_reap);

	return lua_yield(T, bind ? 2 : 1);
}
Example #2
0
File: file.c Project: halfd/lem
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);
}
Example #3
0
static int
db_prepare(lua_State *T)
{
	struct db *db;
	const char *sql;
	size_t len;

	luaL_checktype(T, 1, LUA_TUSERDATA);
	sql = luaL_checklstring(T, 2, &len);

	db = db_unbox(T, 1);
	if (db == NULL)
		return db_closed(T);
	if (db->T != NULL)
		return db_busy(T);

	db->T = T;
	db->refs++;
	db->req.prep.sql = sql;
	db->req.prep.len = len+1;
	lem_async_do(&db->a, db_prepare_work, db_prepare_reap);

	lua_settop(T, 2);
	lua_pushvalue(T, lua_upvalueindex(1));
	return lua_yield(T, 3);
}
Example #4
0
File: file.c Project: halfd/lem
static int
file_readp(lua_State *T)
{
	struct file *f;
	struct lem_parser *p;
	int ret;

	luaL_checktype(T, 1, LUA_TUSERDATA);
	ret = lua_type(T, 2);
	if (ret != LUA_TUSERDATA && ret != LUA_TLIGHTUSERDATA)
		return luaL_argerror(T, 2, "expected userdata");

	f = lua_touserdata(T, 1);
	if (f->fd < 0)
		return io_closed(T);
	if (f->T != NULL)
		return io_busy(T);

	p = lua_touserdata(T, 2);
	if (p->init)
		p->init(T, &f->buf);

	ret = p->process(T, &f->buf);
	if (ret > 0)
		return ret;

	f->T = T;
	f->readp.p = p;
	lem_async_do(&f->a, file_readp_work, file_readp_reap);
	return lua_yield(T, lua_gettop(T));
}
Example #5
0
File: file.c Project: halfd/lem
static int
file_gc(lua_State *T)
{
	struct file *f = lua_touserdata(T, 1);

	lem_debug("collecting %p, fd = %d", f, f->fd);
	if (f->fd >= 0) {
		struct file_gc *gc = lem_xmalloc(sizeof(struct file_gc));

		gc->fd = f->fd;
		f->fd = -1;
		lem_async_do(&gc->a, file_gc_work, NULL);
	}

	return 0;
}
Example #6
0
File: file.c Project: halfd/lem
static int
file_close(lua_State *T)
{
	struct file *f;

	luaL_checktype(T, 1, LUA_TUSERDATA);
	f = lua_touserdata(T, 1);
	if (f->fd < 0)
		return io_closed(T);
	if (f->T != NULL)
		return io_busy(T);

	f->T = T;
	lem_async_do(&f->a, file_close_work, file_close_reap);
	lua_settop(T, 1);
	return lua_yield(T, 1);
}
Example #7
0
static int
stmt_step(lua_State *T)
{
	struct stmt *stmt;
	struct db *db;

	luaL_checktype(T, 1, LUA_TUSERDATA);
	stmt = lua_touserdata(T, 1);
	if (stmt->handle == NULL)
		return stmt_finalized(T);
	db = stmt->db;
	if (db->T != NULL)
		return db_busy(T);

	db->T = T;
	db->req.prep.stmt = stmt->handle;
	lem_async_do(&db->a, db_step_work, stmt_step_reap);

	lua_settop(T, 1);
	return lua_yield(T, 1);
}
Example #8
0
File: stream.c Project: esmil/lem
static int
stream_sendfile(lua_State *T)
{
	struct stream *s;
	struct file *f;
	off_t size;
	off_t offset;
	struct sfhandle *sf;

	luaL_checktype(T, 1, LUA_TUSERDATA);
	luaL_checktype(T, 2, LUA_TUSERDATA);
	size = (off_t)luaL_checknumber(T, 3);
	offset = (off_t)luaL_optnumber(T, 4, 0);

	s = lua_touserdata(T, 1);
	if (!s->open)
		return io_closed(T);
	if (s->w.data != NULL)
		return io_busy(T);

	f = lua_touserdata(T, 2);
	if (f->fd < 0) {
		lua_pushnil(T);
		lua_pushliteral(T, "file closed");
		return 2;
	}

	s->w.data = T;

	sf = lem_xmalloc(sizeof(struct sfhandle));
	sf->T = T;
	sf->s = s;
	sf->size = size;
	sf->offset = offset;
	sf->fd = f->fd;
	lem_async_do(&sf->a, stream_sendfile_work, stream_sendfile_reap);

	lua_settop(T, 2);
	return lua_yield(T, 2);
}
Example #9
0
static int
db_open(lua_State *T)
{
	const char *filename = luaL_checkstring(T, 1);
#if SQLITE_VERSION_NUMBER >= 3005000
	int flags = luaL_optnumber(T, 2, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
#endif
	struct db *db;

	db = lem_xmalloc(sizeof(struct db));
	db->T = T;
	db->handle = NULL;
	db->refs = 1;
	db->req.open.filename = filename;
#if SQLITE_VERSION_NUMBER >= 3005000
	db->req.open.flags = flags;
#endif
	lem_async_do(&db->a, db_open_work, db_open_reap);

	lua_settop(T, 1);
	lua_pushvalue(T, lua_upvalueindex(1));
	return lua_yield(T, 2);
}
Example #10
0
File: file.c Project: halfd/lem
static int
file_write(lua_State *T)
{
	struct file *f;
	const char *str;
	size_t len;
	int idx;
	int i;
	int top;

	luaL_checktype(T, 1, LUA_TUSERDATA);
	top = lua_gettop(T);
	idx = 1;
	do {
		str = luaL_checklstring(T, ++idx, &len);
	} while (len == 0 && idx < top);
	for (i = idx+1; i <= top; i++)
		(void)luaL_checkstring(T, i);

	f = lua_touserdata(T, 1);
	if (f->fd < 0)
		return io_closed(T);
	if (f->T != NULL)
		return io_busy(T);
	if (len == 0) {
		lua_pushboolean(T, 1);
		return 1;
	}

	f->T = T;
	f->write.str = str;
	f->write.len = len;
	f->write.idx = idx;
	lem_async_do(&f->a, file_write_work, file_write_reap);

	return lua_yield(T, top);
}
Example #11
0
File: file.c Project: halfd/lem
/*
 * file:lock() method
 */
static void
file_lock_work(struct lem_async *a)
{
	struct file *f = (struct file *)a;
	struct flock fl = {
		.l_type = f->lock.type,
		.l_whence = SEEK_SET,
		.l_start = f->lock.start,
		.l_len = f->lock.len,
	};

	if (fcntl(f->fd, F_SETLK, &fl) == -1)
		f->ret = errno;
	else
		f->ret = 0;
}

static void
file_lock_reap(struct lem_async *a)
{
	struct file *f = (struct file *)a;
	lua_State *T = f->T;

	f->T = NULL;

	if (f->ret) {
		lem_queue(T, io_strerror(T, f->ret));
		return;
	}

	lua_pushboolean(T, 1);
	lem_queue(T, 1);
}

static int
file_lock(lua_State *T)
{
	static const short mode[] = { F_RDLCK, F_WRLCK, F_UNLCK };
	static const char *const modenames[] = { "r", "w", "u", NULL };
	struct file *f;
	int op;
	lua_Number start;
	lua_Number len;

	luaL_checktype(T, 1, LUA_TUSERDATA);
	op = luaL_checkoption(T, 2, NULL, modenames);
	start = luaL_optnumber(T, 3, 0);
	len = luaL_optnumber(T, 4, 0);
	f = lua_touserdata(T, 1);
	f->lock.start = (off_t)start;
	luaL_argcheck(T, (lua_Number)f->lock.start == start, 3,
			"not an integer in proper range");
	f->lock.len = (off_t)len;
	luaL_argcheck(T, (lua_Number)f->lock.len == len, 4,
			"not an integer in proper range");
	if (f->fd < 0)
		return io_closed(T);
	if (f->T != NULL)
		return io_busy(T);

	f->T = T;
	f->lock.type = mode[op];
	lem_async_do(&f->a, file_lock_work, file_lock_reap);

	lua_settop(T, 1);
	return lua_yield(T, 1);
}