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;