# HG changeset patch # User jbe # Date 1428360450 -7200 # Node ID 9fa3a36733ff7e9a48c4e4877824dce873e69f03 # Parent ef552870f1b66648ce79e5ac6fb06b4f8d32b2da New I/O methods drain and drain_nb diff -r ef552870f1b6 -r 9fa3a36733ff moonbridge_io.c --- a/moonbridge_io.c Mon Apr 06 22:58:51 2015 +0200 +++ b/moonbridge_io.c Tue Apr 07 00:47:30 2015 +0200 @@ -4,9 +4,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -23,7 +20,6 @@ char errmsg[MOONBR_IO_MAXSTRERRORLEN]; \ strerror_r(errno, errmsg, MOONBR_IO_MAXSTRERRORLEN) - #define MOONBR_IO_HANDLE_MT_REGKEY "moonbridge_io_handle" #define MOONBR_IO_HANDLE_PUBLIC_MT_REGKEY "moonbridge_io_handle_public" @@ -65,7 +61,7 @@ } } -static int moonbr_io_read_impl(lua_State *L, int nonblocking) { +static int moonbr_io_read_impl(lua_State *L, int nonblocking, int drain) { moonbr_io_handle_t *handle; lua_Integer maxread; const char *terminatorstr; @@ -73,7 +69,7 @@ char terminator; luaL_Buffer luabuf; size_t luabufcnt = 0; - int restcnt; + int endcnt; char *terminatorpos; ssize_t result; handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY); @@ -83,6 +79,7 @@ luaL_argcheck(L, terminatorlen == 1, 3, "single byte expected"); terminator = terminatorstr[0]; } + lua_settop(L, 1); /* return handle on drain, terminator string may be garbage collected */ if (handle->fd < 0) luaL_error(L, "Attempt to read from a closed I/O handle"); if (handle->readerr) { lua_pushnil(L); @@ -90,23 +87,25 @@ return 2; } moonbr_io_handle_set_nonblocking(L, handle, nonblocking); - luaL_buffinit(L, &luabuf); + if (!drain) luaL_buffinit(L, &luabuf); while (1) { - restcnt = -1; + endcnt = -1; if (maxread > 0 && handle->readbufcnt >= maxread - luabufcnt) { - restcnt = maxread - luabufcnt; + endcnt = maxread - luabufcnt; } else if (terminatorlen) { terminatorpos = memchr(handle->readbuf, terminator, handle->readbufcnt); - if (terminatorpos) restcnt = 1 + (terminatorpos - handle->readbuf); + if (terminatorpos) endcnt = 1 + (terminatorpos - handle->readbuf); } - if (restcnt >= 0) { - luaL_addlstring(&luabuf, handle->readbuf, restcnt); - handle->readbufcnt -= restcnt; - memmove(handle->readbuf, handle->readbuf + restcnt, handle->readbufcnt); - luaL_pushresult(&luabuf); + if (endcnt >= 0) { + if (!drain) { + luaL_addlstring(&luabuf, handle->readbuf, endcnt); + luaL_pushresult(&luabuf); + } + handle->readbufcnt -= endcnt; + memmove(handle->readbuf, handle->readbuf + endcnt, handle->readbufcnt); return 1; } - luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt); + if (!drain) luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt); luabufcnt += handle->readbufcnt; handle->readbufcnt = 0; do { @@ -122,18 +121,28 @@ } handle->readbufcnt += result; } - luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt); + if (!drain) { + luaL_addlstring(&luabuf, handle->readbuf, handle->readbufcnt); + luaL_pushresult(&luabuf); + } handle->readbufcnt = 0; - luaL_pushresult(&luabuf); return 1; } static int moonbr_io_read(lua_State *L) { - return moonbr_io_read_impl(L, 0); + return moonbr_io_read_impl(L, 0, 0); } static int moonbr_io_read_nb(lua_State *L) { - return moonbr_io_read_impl(L, 1); + return moonbr_io_read_impl(L, 1, 0); +} + +static int moonbr_io_drain(lua_State *L) { + return moonbr_io_read_impl(L, 0, 1); +} + +static int moonbr_io_drain_nb(lua_State *L) { + return moonbr_io_read_impl(L, 1, 1); } static int moonbr_io_write_impl(lua_State *L, int nonblocking, int flush) { @@ -355,6 +364,8 @@ static const struct luaL_Reg moonbr_io_handle_methods[] = { {"read", moonbr_io_read}, {"read_nb", moonbr_io_read_nb}, + {"drain", moonbr_io_drain}, + {"drain_nb", moonbr_io_drain_nb}, {"write", moonbr_io_write}, {"write_nb", moonbr_io_write_nb}, {"flush", moonbr_io_flush},