diff options
author | Emil Renner Berthing <esmil@mailme.dk> | 2012-12-16 01:47:16 +0100 |
---|---|---|
committer | Emil Renner Berthing <esmil@mailme.dk> | 2012-12-17 10:11:06 +0100 |
commit | f954692a04a301d602eecc8ff18e6e3d2eb7f077 (patch) | |
tree | c6ae471b0471f276569ff12c83fcbba3d05ccbff | |
parent | f32ad4fb32c6f7043c884860e8209ba0b5be4720 (diff) | |
download | lem-f954692a04a301d602eecc8ff18e6e3d2eb7f077.tar.gz lem-f954692a04a301d602eecc8ff18e6e3d2eb7f077.tar.xz lem-f954692a04a301d602eecc8ff18e6e3d2eb7f077.zip |
io: add file:size() method
-rw-r--r-- | lem/io/core.c | 3 | ||||
-rw-r--r-- | lem/io/file.c | 55 |
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 |