diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2007-06-11 23:44:54 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2007-06-11 23:44:54 +0000 |
| commit | 3cd10f5ab6cda5c4a8db829dd38f25168edcfc4a (patch) | |
| tree | f0c49eb250f5375414025a9e7022261e729ad905 | |
| parent | 3074a8f56b5153f4477e662453102583d7b6f539 (diff) | |
| download | luasocket-3cd10f5ab6cda5c4a8db829dd38f25168edcfc4a.tar.gz luasocket-3cd10f5ab6cda5c4a8db829dd38f25168edcfc4a.tar.bz2 luasocket-3cd10f5ab6cda5c4a8db829dd38f25168edcfc4a.zip | |
Crashy bug fixed in recvraw.
Also fixed returns on closed socket.
| -rw-r--r-- | config | 6 | ||||
| -rw-r--r-- | doc/socket.html | 10 | ||||
| -rw-r--r-- | etc/dispatch.lua | 4 | ||||
| -rw-r--r-- | makefile.dist | 5 | ||||
| -rw-r--r-- | src/buffer.c | 15 | ||||
| -rw-r--r-- | src/luasocket.h | 4 | ||||
| -rw-r--r-- | src/mime.h | 4 | ||||
| -rw-r--r-- | src/mime.lua | 3 | ||||
| -rw-r--r-- | src/usocket.c | 8 | ||||
| -rw-r--r-- | src/wsocket.c | 8 | ||||
| -rw-r--r-- | test/testclnt.lua | 61 | ||||
| -rw-r--r-- | test/testmesg.lua | 2 |
12 files changed, 97 insertions, 33 deletions
| @@ -6,8 +6,8 @@ | |||
| 6 | # Output file names | 6 | # Output file names |
| 7 | # | 7 | # |
| 8 | EXT=so | 8 | EXT=so |
| 9 | SOCKET_V=2.0.1 | 9 | SOCKET_V=2.0.2 |
| 10 | MIME_V=1.0.1 | 10 | MIME_V=1.0.2 |
| 11 | SOCKET_SO=socket.$(EXT).$(SOCKET_V) | 11 | SOCKET_SO=socket.$(EXT).$(SOCKET_V) |
| 12 | MIME_SO=mime.$(EXT).$(MIME_V) | 12 | MIME_SO=mime.$(EXT).$(MIME_V) |
| 13 | UNIX_SO=unix.$(EXT) | 13 | UNIX_SO=unix.$(EXT) |
| @@ -41,7 +41,7 @@ INSTALL_EXEC=cp | |||
| 41 | # for Mac OS X | 41 | # for Mac OS X |
| 42 | # | 42 | # |
| 43 | CC=gcc | 43 | CC=gcc |
| 44 | DEF=-DLUASOCKET_DEBUG -DUNIX_HAS_SUN_LEN | 44 | DEF= -DAAA -DLUASOCKET_DEBUG -DUNIX_HAS_SUN_LEN |
| 45 | CFLAGS= $(LUAINC) -I$(COMPAT) $(DEF) -pedantic -Wall -O2 -fno-common | 45 | CFLAGS= $(LUAINC) -I$(COMPAT) $(DEF) -pedantic -Wall -O2 -fno-common |
| 46 | LDFLAGS=-bundle -undefined dynamic_lookup | 46 | LDFLAGS=-bundle -undefined dynamic_lookup |
| 47 | LD=export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc | 47 | LD=export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc |
diff --git a/doc/socket.html b/doc/socket.html index 16a025b..f096e4b 100644 --- a/doc/socket.html +++ b/doc/socket.html | |||
| @@ -190,11 +190,13 @@ be empty tables or <tt><b>nil</b></tt>. Non-socket values (or values with | |||
| 190 | non-numeric indices) in the arrays will be silently ignored. | 190 | non-numeric indices) in the arrays will be silently ignored. |
| 191 | </p> | 191 | </p> |
| 192 | 192 | ||
| 193 | <p class=return> The function returns a table with the sockets ready for | 193 | <p class=return> The function returns a list with the sockets ready for |
| 194 | reading, a table with the sockets ready for writing and an error message. | 194 | reading, a list with the sockets ready for writing and an error message. |
| 195 | The error message is "<tt>timeout</tt>" if a timeout condition was met and | 195 | The error message is "<tt>timeout</tt>" if a timeout condition was met and |
| 196 | <tt><b>nil</b></tt> otherwise. The returned tables are associative, to | 196 | <tt><b>nil</b></tt> otherwise. The returned tables are |
| 197 | simplify the test if a specific socket has changed status. | 197 | doubly keyed both by integers and also by the sockets |
| 198 | themselves, to simplify the test if a specific socket has | ||
| 199 | changed status. | ||
| 198 | </p> | 200 | </p> |
| 199 | 201 | ||
| 200 | <p class=note> | 202 | <p class=note> |
diff --git a/etc/dispatch.lua b/etc/dispatch.lua index 6f3855e..3ef1e72 100644 --- a/etc/dispatch.lua +++ b/etc/dispatch.lua | |||
| @@ -56,7 +56,7 @@ function socket.protect(f) | |||
| 56 | if not status then | 56 | if not status then |
| 57 | if type(results[1]) == 'table' then | 57 | if type(results[1]) == 'table' then |
| 58 | return nil, results[1][1] | 58 | return nil, results[1][1] |
| 59 | else error(results[1]) end | 59 | else base.error(results[1]) end |
| 60 | end | 60 | end |
| 61 | if coroutine.status(co) == "suspended" then | 61 | if coroutine.status(co) == "suspended" then |
| 62 | arg = {coroutine.yield(base.unpack(results))} | 62 | arg = {coroutine.yield(base.unpack(results))} |
| @@ -219,7 +219,7 @@ function schedule(cortn, status, operation, tcp) | |||
| 219 | operation.cortn[tcp] = cortn | 219 | operation.cortn[tcp] = cortn |
| 220 | operation.stamp[tcp] = socket.gettime() | 220 | operation.stamp[tcp] = socket.gettime() |
| 221 | end | 221 | end |
| 222 | else error(operation) end | 222 | else base.error(operation) end |
| 223 | end | 223 | end |
| 224 | 224 | ||
| 225 | function kick(operation, tcp) | 225 | function kick(operation, tcp) |
diff --git a/makefile.dist b/makefile.dist index e3b0e5c..58ae5b3 100644 --- a/makefile.dist +++ b/makefile.dist | |||
| @@ -1,9 +1,7 @@ | |||
| 1 | #-------------------------------------------------------------------------- | 1 | #-------------------------------------------------------------------------- |
| 2 | # Distribution makefile | 2 | # Distribution makefile |
| 3 | #-------------------------------------------------------------------------- | 3 | #-------------------------------------------------------------------------- |
| 4 | DIST = luasocket-2.0.1 | 4 | DIST = luasocket-2.0.2 |
| 5 | |||
| 6 | COMPAT = src/compat-5.1r5 | ||
| 7 | 5 | ||
| 8 | TEST = \ | 6 | TEST = \ |
| 9 | test/README \ | 7 | test/README \ |
| @@ -115,7 +113,6 @@ dist: | |||
| 115 | 113 | ||
| 116 | mkdir -p $(DIST)/src | 114 | mkdir -p $(DIST)/src |
| 117 | cp -vf $(SRC) $(DIST)/src | 115 | cp -vf $(SRC) $(DIST)/src |
| 118 | cp -vfr $(COMPAT) $(DIST)/src | ||
| 119 | 116 | ||
| 120 | mkdir -p $(DIST)/doc | 117 | mkdir -p $(DIST)/doc |
| 121 | cp -vf $(DOC) $(DIST)/doc | 118 | cp -vf $(DOC) $(DIST)/doc |
diff --git a/src/buffer.c b/src/buffer.c index df1a0bc..de817b2 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -75,12 +75,12 @@ int buffer_meth_setstats(lua_State *L, p_buffer buf) { | |||
| 75 | \*-------------------------------------------------------------------------*/ | 75 | \*-------------------------------------------------------------------------*/ |
| 76 | int buffer_meth_send(lua_State *L, p_buffer buf) { | 76 | int buffer_meth_send(lua_State *L, p_buffer buf) { |
| 77 | int top = lua_gettop(L); | 77 | int top = lua_gettop(L); |
| 78 | p_timeout tm = timeout_markstart(buf->tm); | ||
| 79 | int err = IO_DONE; | 78 | int err = IO_DONE; |
| 80 | size_t size = 0, sent = 0; | 79 | size_t size = 0, sent = 0; |
| 81 | const char *data = luaL_checklstring(L, 2, &size); | 80 | const char *data = luaL_checklstring(L, 2, &size); |
| 82 | long start = (long) luaL_optnumber(L, 3, 1); | 81 | long start = (long) luaL_optnumber(L, 3, 1); |
| 83 | long end = (long) luaL_optnumber(L, 4, -1); | 82 | long end = (long) luaL_optnumber(L, 4, -1); |
| 83 | p_timeout tm = timeout_markstart(buf->tm); | ||
| 84 | if (start < 0) start = (long) (size+start+1); | 84 | if (start < 0) start = (long) (size+start+1); |
| 85 | if (end < 0) end = (long) (size+end+1); | 85 | if (end < 0) end = (long) (size+end+1); |
| 86 | if (start < 1) start = (long) 1; | 86 | if (start < 1) start = (long) 1; |
| @@ -108,10 +108,10 @@ int buffer_meth_send(lua_State *L, p_buffer buf) { | |||
| 108 | \*-------------------------------------------------------------------------*/ | 108 | \*-------------------------------------------------------------------------*/ |
| 109 | int buffer_meth_receive(lua_State *L, p_buffer buf) { | 109 | int buffer_meth_receive(lua_State *L, p_buffer buf) { |
| 110 | int err = IO_DONE, top = lua_gettop(L); | 110 | int err = IO_DONE, top = lua_gettop(L); |
| 111 | p_timeout tm = timeout_markstart(buf->tm); | ||
| 112 | luaL_Buffer b; | 111 | luaL_Buffer b; |
| 113 | size_t size; | 112 | size_t size; |
| 114 | const char *part = luaL_optlstring(L, 3, "", &size); | 113 | const char *part = luaL_optlstring(L, 3, "", &size); |
| 114 | p_timeout tm = timeout_markstart(buf->tm); | ||
| 115 | /* initialize buffer with optional extra prefix | 115 | /* initialize buffer with optional extra prefix |
| 116 | * (useful for concatenating previous partial results) */ | 116 | * (useful for concatenating previous partial results) */ |
| 117 | luaL_buffinit(L, &b); | 117 | luaL_buffinit(L, &b); |
| @@ -182,13 +182,14 @@ static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent) { | |||
| 182 | static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b) { | 182 | static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b) { |
| 183 | int err = IO_DONE; | 183 | int err = IO_DONE; |
| 184 | size_t total = 0; | 184 | size_t total = 0; |
| 185 | while (total < wanted && err == IO_DONE) { | 185 | while (err == IO_DONE) { |
| 186 | size_t count; const char *data; | 186 | size_t count; const char *data; |
| 187 | err = buffer_get(buf, &data, &count); | 187 | err = buffer_get(buf, &data, &count); |
| 188 | count = MIN(count, wanted - total); | 188 | count = MIN(count, wanted - total); |
| 189 | luaL_addlstring(b, data, count); | 189 | luaL_addlstring(b, data, count); |
| 190 | buffer_skip(buf, count); | 190 | buffer_skip(buf, count); |
| 191 | total += count; | 191 | total += count; |
| 192 | if (total >= wanted) break; | ||
| 192 | } | 193 | } |
| 193 | return err; | 194 | return err; |
| 194 | } | 195 | } |
| @@ -198,14 +199,18 @@ static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b) { | |||
| 198 | \*-------------------------------------------------------------------------*/ | 199 | \*-------------------------------------------------------------------------*/ |
| 199 | static int recvall(p_buffer buf, luaL_Buffer *b) { | 200 | static int recvall(p_buffer buf, luaL_Buffer *b) { |
| 200 | int err = IO_DONE; | 201 | int err = IO_DONE; |
| 202 | size_t total = 0; | ||
| 201 | while (err == IO_DONE) { | 203 | while (err == IO_DONE) { |
| 202 | const char *data; size_t count; | 204 | const char *data; size_t count; |
| 203 | err = buffer_get(buf, &data, &count); | 205 | err = buffer_get(buf, &data, &count); |
| 206 | total += count; | ||
| 204 | luaL_addlstring(b, data, count); | 207 | luaL_addlstring(b, data, count); |
| 205 | buffer_skip(buf, count); | 208 | buffer_skip(buf, count); |
| 206 | } | 209 | } |
| 207 | if (err == IO_CLOSED) return IO_DONE; | 210 | if (err == IO_CLOSED) { |
| 208 | else return err; | 211 | if (total > 0) return IO_DONE; |
| 212 | else return IO_CLOSED; | ||
| 213 | } else return err; | ||
| 209 | } | 214 | } |
| 210 | 215 | ||
| 211 | /*-------------------------------------------------------------------------*\ | 216 | /*-------------------------------------------------------------------------*\ |
diff --git a/src/luasocket.h b/src/luasocket.h index 46b5d06..13134cf 100644 --- a/src/luasocket.h +++ b/src/luasocket.h | |||
| @@ -13,8 +13,8 @@ | |||
| 13 | /*-------------------------------------------------------------------------*\ | 13 | /*-------------------------------------------------------------------------*\ |
| 14 | * Current socket library version | 14 | * Current socket library version |
| 15 | \*-------------------------------------------------------------------------*/ | 15 | \*-------------------------------------------------------------------------*/ |
| 16 | #define LUASOCKET_VERSION "LuaSocket 2.0.1" | 16 | #define LUASOCKET_VERSION "LuaSocket 2.0.2" |
| 17 | #define LUASOCKET_COPYRIGHT "Copyright (C) 2004-2006 Diego Nehab" | 17 | #define LUASOCKET_COPYRIGHT "Copyright (C) 2004-2007 Diego Nehab" |
| 18 | #define LUASOCKET_AUTHORS "Diego Nehab" | 18 | #define LUASOCKET_AUTHORS "Diego Nehab" |
| 19 | 19 | ||
| 20 | /*-------------------------------------------------------------------------*\ | 20 | /*-------------------------------------------------------------------------*\ |
| @@ -15,8 +15,8 @@ | |||
| 15 | /*-------------------------------------------------------------------------*\ | 15 | /*-------------------------------------------------------------------------*\ |
| 16 | * Current MIME library version | 16 | * Current MIME library version |
| 17 | \*-------------------------------------------------------------------------*/ | 17 | \*-------------------------------------------------------------------------*/ |
| 18 | #define MIME_VERSION "MIME 1.0.1" | 18 | #define MIME_VERSION "MIME 1.0.2" |
| 19 | #define MIME_COPYRIGHT "Copyright (C) 2004-2006 Diego Nehab" | 19 | #define MIME_COPYRIGHT "Copyright (C) 2004-2007 Diego Nehab" |
| 20 | #define MIME_AUTHORS "Diego Nehab" | 20 | #define MIME_AUTHORS "Diego Nehab" |
| 21 | 21 | ||
| 22 | /*-------------------------------------------------------------------------*\ | 22 | /*-------------------------------------------------------------------------*\ |
diff --git a/src/mime.lua b/src/mime.lua index 3182545..eb75db2 100644 --- a/src/mime.lua +++ b/src/mime.lua | |||
| @@ -27,7 +27,8 @@ local function choose(table) | |||
| 27 | name, opt1, opt2 = "default", name, opt1 | 27 | name, opt1, opt2 = "default", name, opt1 |
| 28 | end | 28 | end |
| 29 | local f = table[name or "nil"] | 29 | local f = table[name or "nil"] |
| 30 | if not f then error("unknown key (" .. base.tostring(name) .. ")", 3) | 30 | if not f then |
| 31 | base.error("unknown key (" .. base.tostring(name) .. ")", 3) | ||
| 31 | else return f(opt1, opt2) end | 32 | else return f(opt1, opt2) end |
| 32 | end | 33 | end |
| 33 | end | 34 | end |
diff --git a/src/usocket.c b/src/usocket.c index e70806a..ef275b4 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
| @@ -206,10 +206,10 @@ int socket_send(p_socket ps, const char *data, size_t count, | |||
| 206 | size_t *sent, p_timeout tm) | 206 | size_t *sent, p_timeout tm) |
| 207 | { | 207 | { |
| 208 | int err; | 208 | int err; |
| 209 | *sent = 0; | ||
| 209 | /* avoid making system calls on closed sockets */ | 210 | /* avoid making system calls on closed sockets */ |
| 210 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | 211 | if (*ps == SOCKET_INVALID) return IO_CLOSED; |
| 211 | /* loop until we send something or we give up on error */ | 212 | /* loop until we send something or we give up on error */ |
| 212 | *sent = 0; | ||
| 213 | for ( ;; ) { | 213 | for ( ;; ) { |
| 214 | long put = (long) send(*ps, data, count, 0); | 214 | long put = (long) send(*ps, data, count, 0); |
| 215 | /* if we sent anything, we are done */ | 215 | /* if we sent anything, we are done */ |
| @@ -239,8 +239,8 @@ int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, | |||
| 239 | SA *addr, socklen_t len, p_timeout tm) | 239 | SA *addr, socklen_t len, p_timeout tm) |
| 240 | { | 240 | { |
| 241 | int err; | 241 | int err; |
| 242 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||
| 243 | *sent = 0; | 242 | *sent = 0; |
| 243 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||
| 244 | for ( ;; ) { | 244 | for ( ;; ) { |
| 245 | long put = (long) sendto(*ps, data, count, 0, addr, len); | 245 | long put = (long) sendto(*ps, data, count, 0, addr, len); |
| 246 | if (put > 0) { | 246 | if (put > 0) { |
| @@ -261,6 +261,7 @@ int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, | |||
| 261 | \*-------------------------------------------------------------------------*/ | 261 | \*-------------------------------------------------------------------------*/ |
| 262 | int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { | 262 | int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { |
| 263 | int err; | 263 | int err; |
| 264 | *got = 0; | ||
| 264 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | 265 | if (*ps == SOCKET_INVALID) return IO_CLOSED; |
| 265 | for ( ;; ) { | 266 | for ( ;; ) { |
| 266 | long taken = (long) recv(*ps, data, count, 0); | 267 | long taken = (long) recv(*ps, data, count, 0); |
| @@ -269,7 +270,6 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm | |||
| 269 | return IO_DONE; | 270 | return IO_DONE; |
| 270 | } | 271 | } |
| 271 | err = errno; | 272 | err = errno; |
| 272 | *got = 0; | ||
| 273 | if (taken == 0) return IO_CLOSED; | 273 | if (taken == 0) return IO_CLOSED; |
| 274 | if (err == EINTR) continue; | 274 | if (err == EINTR) continue; |
| 275 | if (err != EAGAIN) return err; | 275 | if (err != EAGAIN) return err; |
| @@ -284,6 +284,7 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm | |||
| 284 | int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, | 284 | int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, |
| 285 | SA *addr, socklen_t *len, p_timeout tm) { | 285 | SA *addr, socklen_t *len, p_timeout tm) { |
| 286 | int err; | 286 | int err; |
| 287 | *got = 0; | ||
| 287 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | 288 | if (*ps == SOCKET_INVALID) return IO_CLOSED; |
| 288 | for ( ;; ) { | 289 | for ( ;; ) { |
| 289 | long taken = (long) recvfrom(*ps, data, count, 0, addr, len); | 290 | long taken = (long) recvfrom(*ps, data, count, 0, addr, len); |
| @@ -292,7 +293,6 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, | |||
| 292 | return IO_DONE; | 293 | return IO_DONE; |
| 293 | } | 294 | } |
| 294 | err = errno; | 295 | err = errno; |
| 295 | *got = 0; | ||
| 296 | if (taken == 0) return IO_CLOSED; | 296 | if (taken == 0) return IO_CLOSED; |
| 297 | if (err == EINTR) continue; | 297 | if (err == EINTR) continue; |
| 298 | if (err != EAGAIN) return err; | 298 | if (err != EAGAIN) return err; |
diff --git a/src/wsocket.c b/src/wsocket.c index dce333b..e247777 100644 --- a/src/wsocket.c +++ b/src/wsocket.c | |||
| @@ -201,10 +201,10 @@ int socket_send(p_socket ps, const char *data, size_t count, | |||
| 201 | size_t *sent, p_timeout tm) | 201 | size_t *sent, p_timeout tm) |
| 202 | { | 202 | { |
| 203 | int err; | 203 | int err; |
| 204 | *sent = 0; | ||
| 204 | /* avoid making system calls on closed sockets */ | 205 | /* avoid making system calls on closed sockets */ |
| 205 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | 206 | if (*ps == SOCKET_INVALID) return IO_CLOSED; |
| 206 | /* loop until we send something or we give up on error */ | 207 | /* loop until we send something or we give up on error */ |
| 207 | *sent = 0; | ||
| 208 | for ( ;; ) { | 208 | for ( ;; ) { |
| 209 | /* try to send something */ | 209 | /* try to send something */ |
| 210 | int put = send(*ps, data, (int) count, 0); | 210 | int put = send(*ps, data, (int) count, 0); |
| @@ -231,8 +231,8 @@ int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, | |||
| 231 | SA *addr, socklen_t len, p_timeout tm) | 231 | SA *addr, socklen_t len, p_timeout tm) |
| 232 | { | 232 | { |
| 233 | int err; | 233 | int err; |
| 234 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||
| 235 | *sent = 0; | 234 | *sent = 0; |
| 235 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||
| 236 | for ( ;; ) { | 236 | for ( ;; ) { |
| 237 | int put = sendto(*ps, data, (int) count, 0, addr, len); | 237 | int put = sendto(*ps, data, (int) count, 0, addr, len); |
| 238 | if (put > 0) { | 238 | if (put > 0) { |
| @@ -251,8 +251,8 @@ int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, | |||
| 251 | \*-------------------------------------------------------------------------*/ | 251 | \*-------------------------------------------------------------------------*/ |
| 252 | int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { | 252 | int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { |
| 253 | int err; | 253 | int err; |
| 254 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||
| 255 | *got = 0; | 254 | *got = 0; |
| 255 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||
| 256 | for ( ;; ) { | 256 | for ( ;; ) { |
| 257 | int taken = recv(*ps, data, (int) count, 0); | 257 | int taken = recv(*ps, data, (int) count, 0); |
| 258 | if (taken > 0) { | 258 | if (taken > 0) { |
| @@ -273,8 +273,8 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm | |||
| 273 | int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, | 273 | int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, |
| 274 | SA *addr, socklen_t *len, p_timeout tm) { | 274 | SA *addr, socklen_t *len, p_timeout tm) { |
| 275 | int err; | 275 | int err; |
| 276 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||
| 277 | *got = 0; | 276 | *got = 0; |
| 277 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||
| 278 | for ( ;; ) { | 278 | for ( ;; ) { |
| 279 | int taken = recvfrom(*ps, data, (int) count, 0, addr, len); | 279 | int taken = recvfrom(*ps, data, (int) count, 0, addr, len); |
| 280 | if (taken > 0) { | 280 | if (taken > 0) { |
diff --git a/test/testclnt.lua b/test/testclnt.lua index 304cfd3..2f4ffad 100644 --- a/test/testclnt.lua +++ b/test/testclnt.lua | |||
| @@ -498,7 +498,63 @@ remote(string.format([[ | |||
| 498 | end | 498 | end |
| 499 | 499 | ||
| 500 | ------------------------------------------------------------------------ | 500 | ------------------------------------------------------------------------ |
| 501 | 501 | function test_readafterclose() | |
| 502 | local back, partial, err | ||
| 503 | local str = 'little string' | ||
| 504 | reconnect() | ||
| 505 | pass("trying repeated '*a' pattern") | ||
| 506 | remote (string.format ([[ | ||
| 507 | data:send('%s') | ||
| 508 | data:close() | ||
| 509 | data = nil | ||
| 510 | ]], str)) | ||
| 511 | back, err, partial = data:receive("*a") | ||
| 512 | assert(back == str, "unexpected data read") | ||
| 513 | back, err, partial = data:receive("*a") | ||
| 514 | assert(back == nil and err == "closed", "should have returned 'closed'") | ||
| 515 | print("ok") | ||
| 516 | reconnect() | ||
| 517 | pass("trying active close before '*a'") | ||
| 518 | remote (string.format ([[ | ||
| 519 | data:close() | ||
| 520 | data = nil | ||
| 521 | ]])) | ||
| 522 | data:close() | ||
| 523 | back, err, partial = data:receive("*a") | ||
| 524 | assert(back == nil and err == "closed", "should have returned 'closed'") | ||
| 525 | print("ok") | ||
| 526 | reconnect() | ||
| 527 | pass("trying active close before '*l'") | ||
| 528 | remote (string.format ([[ | ||
| 529 | data:close() | ||
| 530 | data = nil | ||
| 531 | ]])) | ||
| 532 | data:close() | ||
| 533 | back, err, partial = data:receive() | ||
| 534 | assert(back == nil and err == "closed", "should have returned 'closed'") | ||
| 535 | print("ok") | ||
| 536 | reconnect() | ||
| 537 | pass("trying active close before raw 1") | ||
| 538 | remote (string.format ([[ | ||
| 539 | data:close() | ||
| 540 | data = nil | ||
| 541 | ]])) | ||
| 542 | data:close() | ||
| 543 | back, err, partial = data:receive(1) | ||
| 544 | assert(back == nil and err == "closed", "should have returned 'closed'") | ||
| 545 | print("ok") | ||
| 546 | reconnect() | ||
| 547 | pass("trying active close before raw 0") | ||
| 548 | remote (string.format ([[ | ||
| 549 | data:close() | ||
| 550 | data = nil | ||
| 551 | ]])) | ||
| 552 | data:close() | ||
| 553 | back, err, partial = data:receive(0) | ||
| 554 | assert(back == nil and err == "closed", "should have returned 'closed'") | ||
| 555 | print("ok") | ||
| 556 | os.exit() | ||
| 557 | end | ||
| 502 | 558 | ||
| 503 | test("method registration") | 559 | test("method registration") |
| 504 | test_methods(socket.tcp(), { | 560 | test_methods(socket.tcp(), { |
| @@ -541,6 +597,9 @@ test_methods(socket.udp(), { | |||
| 541 | "settimeout" | 597 | "settimeout" |
| 542 | }) | 598 | }) |
| 543 | 599 | ||
| 600 | test("testing read after close") | ||
| 601 | test_readafterclose() | ||
| 602 | |||
| 544 | test("select function") | 603 | test("select function") |
| 545 | test_selectbugs() | 604 | test_selectbugs() |
| 546 | 605 | ||
diff --git a/test/testmesg.lua b/test/testmesg.lua index 04305f4..580693b 100644 --- a/test/testmesg.lua +++ b/test/testmesg.lua | |||
| @@ -62,7 +62,7 @@ source = smtp.message{ | |||
| 62 | headers = { | 62 | headers = { |
| 63 | ["ConTenT-tYpE"] = 'image/png; name="luasocket.png"', | 63 | ["ConTenT-tYpE"] = 'image/png; name="luasocket.png"', |
| 64 | ["content-disposition"] = 'attachment; filename="luasocket.png"', | 64 | ["content-disposition"] = 'attachment; filename="luasocket.png"', |
| 65 | ["content-description"] = 'a beautiful image', | 65 | ["content-description"] = 'our logo', |
| 66 | ["content-transfer-encoding"] = "BASE64" | 66 | ["content-transfer-encoding"] = "BASE64" |
| 67 | }, | 67 | }, |
| 68 | body = ltn12.source.chain( | 68 | body = ltn12.source.chain( |
