summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmil Renner Berthing <esmil@mailme.dk>2012-12-16 01:47:16 +0100
committerEmil Renner Berthing <esmil@mailme.dk>2012-12-17 10:11:06 +0100
commitf954692a04a301d602eecc8ff18e6e3d2eb7f077 (patch)
treec6ae471b0471f276569ff12c83fcbba3d05ccbff
parentf32ad4fb32c6f7043c884860e8209ba0b5be4720 (diff)
downloadlem-f954692a04a301d602eecc8ff18e6e3d2eb7f077.tar.gz
lem-f954692a04a301d602eecc8ff18e6e3d2eb7f077.tar.xz
lem-f954692a04a301d602eecc8ff18e6e3d2eb7f077.zip
io: add file:size() method
-rw-r--r--lem/io/core.c3
-rw-r--r--lem/io/file.c55
2 files changed, 58 insertions, 0 deletions
diff --git a/lem/io/core.c b/lem/io/core.c
index 672961f..f46319e 100644
--- a/lem/io/core.c
+++ b/lem/io/core.c
@@ -283,6 +283,9 @@ luaopen_lem_io_core(lua_State *L)
/* mt.write = <file_write> */
lua_pushcfunction(L, file_write);
lua_setfield(L, -2, "write");
+ /* mt.size = <file_size> */
+ lua_pushcfunction(L, file_size);
+ lua_setfield(L, -2, "size");
/* mt.seek = <file_seek> */
lua_pushcfunction(L, file_seek);
lua_setfield(L, -2, "seek");
diff --git a/lem/io/file.c b/lem/io/file.c
index 07985b8..2015f31 100644
--- a/lem/io/file.c
+++ b/lem/io/file.c
@@ -29,6 +29,9 @@ struct file {
size_t len;
} write;
struct {
+ off_t val;
+ } size;
+ struct {
off_t offset;
int whence;
} seek;
@@ -247,6 +250,58 @@ file_write(lua_State *T)
}
/*
+ * file:size() method
+ */
+static void
+file_size_work(struct lem_async *a)
+{
+ struct file *f = (struct file *)a;
+ struct stat st;
+
+ if (fstat(f->fd, &st)) {
+ f->ret = errno;
+ } else {
+ f->ret = 0;
+ f->size.val = st.st_size;
+ }
+}
+
+static void
+file_size_reap(struct lem_async *a)
+{
+ struct file *f = (struct file *)a;
+ lua_State *T = f->a.T;
+
+ f->a.T = NULL;
+
+ if (f->ret) {
+ lem_queue(T, io_strerror(T, f->ret));
+ return;
+ }
+
+ lua_pushnumber(T, f->size.val);
+ lem_queue(T, 1);
+}
+
+static int
+file_size(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->a.T != NULL)
+ return io_busy(T);
+
+ lem_async_do(&f->a, T, file_size_work, file_size_reap);
+
+ lua_settop(T, 1);
+ return lua_yield(T, 1);
+}
+
+/*
* file:seek() method
*/
static void