moonbridge

changeset 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
files moonbridge.c
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(...) */

Impressum / About Us