moonbridge

diff moonbridge_io.c @ 94:de3982f17d05

Removed timeout option from socket:close(); Simulate shutdown for local sockets (Unix Domain Sockets)
author jbe
date Tue Apr 07 22:17:13 2015 +0200 (2015-04-07)
parents 111b2469b753
children 719f83c7fea4
line diff
     1.1 --- a/moonbridge_io.c	Tue Apr 07 04:08:41 2015 +0200
     1.2 +++ b/moonbridge_io.c	Tue Apr 07 22:17:13 2015 +0200
     1.3 @@ -25,9 +25,9 @@
     1.4  
     1.5  typedef struct {
     1.6    int fd;
     1.7 -  int issocket;
     1.8 -  int canshutdown;
     1.9 -  int shutwr;
    1.10 +  int useshutdown;
    1.11 +  int finished;
    1.12 +  int closed;
    1.13    int nonblocking;
    1.14    int readerr;
    1.15    int readbufcnt;
    1.16 @@ -65,7 +65,7 @@
    1.17  
    1.18  static void moonbr_io_handle_set_linger(lua_State *L, moonbr_io_handle_t *handle, int timeout) {
    1.19    struct linger lingerval = { 0, };
    1.20 -  if (!handle->issocket) return;
    1.21 +  if (!handle->useshutdown) return;
    1.22    if (timeout >= 0) {
    1.23      lingerval.l_onoff = 1;
    1.24      lingerval.l_linger = timeout;
    1.25 @@ -95,7 +95,8 @@
    1.26      terminator = terminatorstr[0];
    1.27    }
    1.28    lua_settop(L, 1);  /* return handle on drain, terminator string may be garbage collected */
    1.29 -  if (handle->fd < 0) luaL_error(L, "Attempt to read from a closed I/O handle");
    1.30 +  if (handle->closed) luaL_error(L, "Attempt to read from a closed I/O handle");
    1.31 +  if (handle->fd < 0) goto moonbr_io_read_impl_eof;  /* fake EOF to simulate shutdown */
    1.32    if (handle->readerr) {
    1.33      lua_pushnil(L);
    1.34      lua_pushliteral(L, "Previous read error");
    1.35 @@ -147,6 +148,7 @@
    1.36    handle->readbufcnt = 0;
    1.37    if (!drain) {
    1.38      if (!luabufcnt && result == 0) {
    1.39 +      moonbr_io_read_impl_eof:
    1.40        lua_pushboolean(L, 0);
    1.41        lua_pushliteral(L, "End of file");
    1.42        return 2;
    1.43 @@ -182,8 +184,8 @@
    1.44    size_t written;
    1.45    ssize_t result;
    1.46    handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY);
    1.47 -  if (handle->fd < 0) luaL_error(L, "Attempt to write to a closed I/O handle");
    1.48 -  if (handle->shutwr) luaL_error(L, "Attempt to write to a finished I/O handle");
    1.49 +  if (handle->closed) luaL_error(L, "Attempt to write to a closed I/O handle");
    1.50 +  if (handle->finished) luaL_error(L, "Attempt to write to a finished I/O handle");
    1.51    if (handle->writeerr) {
    1.52      lua_pushnil(L);
    1.53      lua_pushliteral(L, "Previous write error");
    1.54 @@ -295,34 +297,44 @@
    1.55  static int moonbr_io_finish(lua_State *L) {
    1.56    moonbr_io_handle_t *handle;
    1.57    handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY);
    1.58 -  if (handle->fd < 0) luaL_error(L, "Attempt to finish a closed I/O handle");
    1.59 -  if (handle->shutwr) luaL_error(L, "Attempt to finish a finished I/O handle");
    1.60 -  handle->shutwr = 1;
    1.61 -  if (handle->canshutdown) {
    1.62 -    if (handle->writeleft) {
    1.63 -      lua_pushcfunction(L, moonbr_io_flush);
    1.64 -      lua_pushvalue(L, 1);
    1.65 -      lua_call(L, 1, 2);
    1.66 -      if (!lua_toboolean(L, -2)) return 2;
    1.67 +  if (handle->closed) luaL_error(L, "Attempt to finish a closed I/O handle");
    1.68 +  if (handle->finished) luaL_error(L, "Attempt to finish a finished I/O handle");
    1.69 +  if (handle->writeleft) {
    1.70 +    lua_pushcfunction(L, moonbr_io_flush);
    1.71 +    lua_pushvalue(L, 1);
    1.72 +    lua_call(L, 1, 2);
    1.73 +    if (!lua_toboolean(L, -2)) {
    1.74 +      handle->finished = 1;
    1.75 +      return 2;
    1.76      }
    1.77 +  }
    1.78 +  handle->finished = 1;
    1.79 +  if (handle->useshutdown) {
    1.80      if (shutdown(handle->fd, SHUT_WR)) {
    1.81        moonbr_io_errmsg();
    1.82        lua_pushnil(L);
    1.83        lua_pushstring(L, errmsg);
    1.84        return 2;
    1.85      }
    1.86 +  } else {
    1.87 +    if (close(handle->fd)) {
    1.88 +      moonbr_io_errmsg();
    1.89 +      handle->fd = -1;
    1.90 +      lua_pushnil(L);
    1.91 +      lua_pushstring(L, errmsg);
    1.92 +      return 2;
    1.93 +    }
    1.94 +    handle->fd = -1;  /* fake EOF on read */
    1.95    }
    1.96    lua_pushboolean(L, 1);
    1.97    return 1;
    1.98  }
    1.99  
   1.100 -static int moonbr_io_close(lua_State *L) {
   1.101 +static int moonbr_io_close_impl(lua_State *L, int reset) {
   1.102    moonbr_io_handle_t *handle;
   1.103 -  int timeout;
   1.104    handle = luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY);
   1.105 -  timeout = luaL_optinteger(L, 2, -1);
   1.106 -  if (handle->fd < 0) luaL_error(L, "Attempt to close a closed I/O handle");
   1.107 -  if (timeout != 0) {
   1.108 +  if (handle->closed) luaL_error(L, "Attempt to close a closed I/O handle");
   1.109 +  if (!reset) {
   1.110      if (handle->writeleft) {
   1.111        lua_pushcfunction(L, moonbr_io_flush);
   1.112        lua_pushvalue(L, 1);
   1.113 @@ -333,14 +345,16 @@
   1.114          return 2;
   1.115        }
   1.116      }
   1.117 -    moonbr_io_handle_set_linger(L, handle, timeout);
   1.118 +    moonbr_io_handle_set_linger(L, handle, -1);
   1.119    }
   1.120 -  if (close(handle->fd)) {
   1.121 -    moonbr_io_errmsg();
   1.122 -    handle->fd = -1;
   1.123 -    lua_pushnil(L);
   1.124 -    lua_pushstring(L, errmsg);
   1.125 -    return 2;
   1.126 +  if (handle->fd >= 0) {
   1.127 +    if (close(handle->fd)) {
   1.128 +      moonbr_io_errmsg();
   1.129 +      handle->fd = -1;
   1.130 +      lua_pushnil(L);
   1.131 +      lua_pushstring(L, errmsg);
   1.132 +      return 2;
   1.133 +    }
   1.134    }
   1.135    handle->fd = -1;
   1.136    lua_pushboolean(L, 1);
   1.137 @@ -348,14 +362,12 @@
   1.138  
   1.139  }
   1.140  
   1.141 +static int moonbr_io_close(lua_State *L) {
   1.142 +  return moonbr_io_close_impl(L, 0);
   1.143 +}
   1.144 +
   1.145  static int moonbr_io_reset(lua_State *L) {
   1.146 -  luaL_checkudata(L, 1, MOONBR_IO_HANDLE_MT_REGKEY);
   1.147 -  lua_settop(L, 1);
   1.148 -  lua_pushcfunction(L, moonbr_io_close);
   1.149 -  lua_insert(L, 1);
   1.150 -  lua_pushinteger(L, 0);
   1.151 -  lua_call(L, 2, LUA_MULTRET);
   1.152 -  return lua_gettop(L);
   1.153 +  return moonbr_io_close_impl(L, 1);
   1.154  }
   1.155  
   1.156  static int moonbr_io_gc(lua_State *L) {
   1.157 @@ -381,13 +393,13 @@
   1.158    }
   1.159  }
   1.160  
   1.161 -void moonbr_io_pushhandle(lua_State *L, int fd, int issocket, int canshutdown) {
   1.162 +void moonbr_io_pushhandle(lua_State *L, int fd, int useshutdown) {
   1.163    moonbr_io_handle_t *handle;
   1.164    handle = lua_newuserdata(L, sizeof(moonbr_io_handle_t));
   1.165    handle->fd = fd;
   1.166 -  handle->issocket = issocket;
   1.167 -  handle->canshutdown = canshutdown;
   1.168 -  handle->shutwr = 0;
   1.169 +  handle->useshutdown = useshutdown;
   1.170 +  handle->finished = 0;
   1.171 +  handle->closed = 0;
   1.172    handle->nonblocking = -1;
   1.173    handle->readerr = 0;
   1.174    handle->readbufcnt = 0;

Impressum / About Us