diff options
-rw-r--r-- | stream.c | 37 |
1 files changed, 33 insertions, 4 deletions
@@ -1,6 +1,9 @@ #include "stream.h" +#include <errno.h> #include <stdlib.h> +#include <string.h> +#include <unistd.h> #include <lauxlib.h> #include <lua.h> @@ -12,6 +15,8 @@ int stream_push_new(lua_State * L, const int fd) { struct stream * s = lua_newuserdata(L, sizeof(struct stream)); + memset(s, 0, sizeof(struct stream)); + s->fd = fd; if (1 == luaL_newmetatable(L, "stream")) @@ -91,16 +96,40 @@ int stream_read(lua_State * L) s->in.data = buffer; } - return stream_readk(L, LUA_OK, 0); // Intentionally do not pop Stream that's on top of the stack. + return stream_readk(L, LUA_OK, (lua_KContext) s); // Intentionally do not pop Stream that's on top of the stack. } /// Continuation function and core implementation of the reading operation from a stream. /// \param L Lua state running reading operation /// \param status TODO -/// \param ctx TODO +/// \param ctx Address of the Stream that is being read /// \param Number of the results pushed to the stack int stream_readk(lua_State * L, int status, lua_KContext ctx) { - lua_pop(L, 0); - return 0; + struct stream * s = (struct stream *) ctx; + + int length = read(s->fd, s->in.data, 1023); // TODO: Allow user to control amount of bytes being read. + + if (-1 == length) + { + if (EWOULDBLOCK == errno || EAGAIN == errno) + { + lua_yieldk(L, 0, ctx, stream_readk); + } + else + { + lua_pop(L, 1); + lua_pushstring(L, strerror(errno)); + return lua_error(L); + } + } + + s->in.data[length] = 0; + s->in.length = length; + s->in.offset = 0; + + lua_pushstring(L, s->in.data); + lua_remove(L, -2); + + return 1; } |