moonbridge
diff moonbridge.c @ 76:d4265136ce88
Work on write_nb method
author | jbe |
---|---|
date | Sun Apr 05 00:35:11 2015 +0200 (2015-04-05) |
parents | 9fff0cb4fc65 |
children | 38e7bd13200d |
line diff
1.1 --- a/moonbridge.c Sat Apr 04 23:32:24 2015 +0200 1.2 +++ b/moonbridge.c Sun Apr 05 00:35:11 2015 +0200 1.3 @@ -978,7 +978,7 @@ 1.4 1.5 /* Lua method for socket object to write to output stream using write_nb */ 1.6 static int moonbr_child_lua_write_nb_stream(lua_State *L) { 1.7 - lua_getfield(L, 1, "input"); 1.8 + lua_getfield(L, 1, "output"); 1.9 lua_getfield(L, -1, "write_nb"); 1.10 lua_insert(L, 1); 1.11 lua_replace(L, 2); 1.12 @@ -2483,8 +2483,74 @@ 1.13 } 1.14 1.15 /* New methods for Lua file objects: non-blocking writing */ 1.16 +static int moonbr_io_write_nb_impl(lua_State *L) { 1.17 + luaL_Stream *stream; 1.18 + FILE *file; 1.19 + int argc, i; 1.20 + const char *str; 1.21 + size_t strlen; 1.22 + size_t written; 1.23 + stream = luaL_checkudata(L, 1, LUA_FILEHANDLE); 1.24 + file = stream->f; 1.25 + argc = lua_gettop(L) - 1; 1.26 + for (i=0; i<argc; i++) { 1.27 + str = luaL_checklstring(L, 2+i, &strlen); 1.28 + written = fwrite(str, 1, strlen, file); 1.29 + if (written < strlen) { 1.30 + if (errno == EAGAIN) { 1.31 + luaL_Buffer buf; 1.32 + clearerr(file); 1.33 + luaL_buffinit(L, &buf); 1.34 + luaL_addlstring(&buf, str+written, strlen-written); 1.35 + for (i=i+1; i<argc; i++) { 1.36 + luaL_checkstring(L, 2+i); 1.37 + lua_pushvalue(L, 2+i); 1.38 + luaL_addvalue(&buf); 1.39 + } 1.40 + luaL_pushresult(&buf); 1.41 + return 1; 1.42 + } else { 1.43 + char errmsg[MOONBR_MAXSTRERRORLEN]; 1.44 + strerror_r(errno, errmsg, MOONBR_MAXSTRERRORLEN); /* use thread-safe call in case child created threads */ 1.45 + lua_pushnil(L); 1.46 + lua_pushstring(L, errmsg); 1.47 + return 2; 1.48 + } 1.49 + } 1.50 + } 1.51 + lua_pushliteral(L, ""); 1.52 + return 1; 1.53 +} 1.54 static int moonbr_io_write_nb(lua_State *L) { 1.55 - return luaL_error(L, "Not implemented"); // TODO 1.56 + luaL_Stream *stream; 1.57 + FILE *file; 1.58 + int fd, flags; 1.59 + stream = luaL_checkudata(L, 1, LUA_FILEHANDLE); 1.60 + if (!stream->closef) luaL_error(L, "attempt to use a closed file"); 1.61 + lua_pushcfunction(L, moonbr_io_write_nb_impl); 1.62 + lua_insert(L, 1); 1.63 + file = stream->f; 1.64 + if (ferror(file)) { 1.65 + lua_pushnil(L); 1.66 + lua_pushliteral(L, "Previous error condition on file handle"); 1.67 + return 2; 1.68 + } 1.69 + fd = fileno(file); 1.70 + flags = fcntl(fd, F_GETFL, 0); 1.71 + if (flags == -1) goto moonbr_io_write_nb_error; 1.72 + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) goto moonbr_io_write_nb_error; 1.73 + if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0)) { 1.74 + fcntl(fd, F_SETFL, flags); 1.75 + return lua_error(L); 1.76 + } 1.77 + if (fcntl(fd, F_SETFL, flags) == -1) goto moonbr_io_write_nb_error; 1.78 + return lua_gettop(L); 1.79 + moonbr_io_write_nb_error: 1.80 + { 1.81 + char errmsg[MOONBR_MAXSTRERRORLEN]; 1.82 + strerror_r(errno, errmsg, MOONBR_MAXSTRERRORLEN); /* use thread-safe call in case child created threads */ 1.83 + return luaL_error(L, "Unexpected error in write_nb method: %s", errmsg); 1.84 + } 1.85 } 1.86 1.87 /* New global function timeout(...) */