diff --git a/src/buffer.c b/src/buffer.c index 30be156..a696158 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -59,6 +59,17 @@ int buf_meth_getstats(lua_State *L, p_buf buf) { return 3; } +/*-------------------------------------------------------------------------*\ +* object:setstats() interface +\*-------------------------------------------------------------------------*/ +int buf_meth_setstats(lua_State *L, p_buf buf) { + buf->received = (long) luaL_optnumber(L, 2, buf->received); + buf->sent = (long) luaL_optnumber(L, 3, buf->sent); + if (lua_isnumber(L, 4)) buf->birthday = tm_gettime() - lua_tonumber(L, 4); + lua_pushnumber(L, 1); + return 1; +} + /*-------------------------------------------------------------------------*\ * object:send() interface \*-------------------------------------------------------------------------*/ @@ -68,12 +79,12 @@ int buf_meth_send(lua_State *L, p_buf buf) { int err = IO_DONE; size_t size, sent; const char *data = luaL_checklstring(L, 2, &size); - ssize_t start = (ssize_t) luaL_optnumber(L, 3, 1); - ssize_t end = (ssize_t) luaL_optnumber(L, 4, -1); + long start = (long) luaL_optnumber(L, 3, 1); + long end = (long) luaL_optnumber(L, 4, -1); if (start < 0) start = size+start+1; if (end < 0) end = size+end+1; if (start < 1) start = 1; - if (end > size) end = size; + if (end > (long) size) end = size; if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent); /* check if there was an error */ if (err != IO_DONE) { diff --git a/src/buffer.h b/src/buffer.h index 3cc885f..8e5fb6c 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -41,6 +41,7 @@ void buf_init(p_buf buf, p_io io, p_tm tm); int buf_meth_send(lua_State *L, p_buf buf); int buf_meth_receive(lua_State *L, p_buf buf); int buf_meth_getstats(lua_State *L, p_buf buf); +int buf_meth_setstats(lua_State *L, p_buf buf); int buf_isempty(p_buf buf); #endif /* BUF_H */ diff --git a/src/io.h b/src/io.h index 51801f6..4f9de57 100644 --- a/src/io.h +++ b/src/io.h @@ -64,4 +64,5 @@ typedef t_io *p_io; void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx); const char *io_strerror(int err); -#endif /* IO_H */ \ No newline at end of file +#endif /* IO_H */ + diff --git a/src/luasocket.h b/src/luasocket.h index 716b7ff..14daef5 100644 --- a/src/luasocket.h +++ b/src/luasocket.h @@ -13,7 +13,7 @@ /*-------------------------------------------------------------------------*\ * Current luasocket version \*-------------------------------------------------------------------------*/ -#define LUASOCKET_VERSION "LuaSocket 2.0 (beta)" +#define LUASOCKET_VERSION "LuaSocket 2.0 (beta2)" /*-------------------------------------------------------------------------*\ * This macro prefixes all exported API functions diff --git a/src/socket.lua b/src/socket.lua index ad96ddb..be16efe 100644 --- a/src/socket.lua +++ b/src/socket.lua @@ -90,7 +90,8 @@ socket.sinkt["keep-open"] = function(sock) dirty = function() return sock:dirty() end }, { __call = function(self, chunk, err) - return sock:send(chunk) + if chunk then return sock:send(chunk) + else return 1 end end }) end diff --git a/src/tcp.c b/src/tcp.c index ef5a824..746c4b6 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -24,6 +24,7 @@ static int meth_listen(lua_State *L); static int meth_bind(lua_State *L); static int meth_send(lua_State *L); static int meth_getstats(lua_State *L); +static int meth_setstats(lua_State *L); static int meth_getsockname(lua_State *L); static int meth_getpeername(lua_State *L); static int meth_shutdown(lua_State *L); @@ -49,6 +50,7 @@ static luaL_reg tcp[] = { {"getpeername", meth_getpeername}, {"getsockname", meth_getsockname}, {"getstats", meth_getstats}, + {"setstats", meth_setstats}, {"listen", meth_listen}, {"receive", meth_receive}, {"send", meth_send}, @@ -117,6 +119,11 @@ static int meth_getstats(lua_State *L) { return buf_meth_getstats(L, &tcp->buf); } +static int meth_setstats(lua_State *L) { + p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); + return buf_meth_setstats(L, &tcp->buf); +} + /*-------------------------------------------------------------------------*\ * Just call option handler \*-------------------------------------------------------------------------*/ diff --git a/src/unix.c b/src/unix.c index 407f85d..1e0e252 100644 --- a/src/unix.c +++ b/src/unix.c @@ -33,11 +33,11 @@ static int meth_getfd(lua_State *L); static int meth_setfd(lua_State *L); static int meth_dirty(lua_State *L); -static const char *unix_tryconnect(p_unix unix, const char *path); -static const char *unix_trybind(p_unix unix, const char *path); +static const char *unix_tryconnect(p_unix un, const char *path); +static const char *unix_trybind(p_unix un, const char *path); /* unix object methods */ -static luaL_reg unix[] = { +static luaL_reg un[] = { {"__gc", meth_close}, {"__tostring", aux_tostring}, {"accept", meth_accept}, @@ -77,9 +77,9 @@ static luaL_reg func[] = { \*-------------------------------------------------------------------------*/ int unix_open(lua_State *L) { /* create classes */ - aux_newclass(L, "unix{master}", unix); - aux_newclass(L, "unix{client}", unix); - aux_newclass(L, "unix{server}", unix); + aux_newclass(L, "unix{master}", un); + aux_newclass(L, "unix{client}", un); + aux_newclass(L, "unix{server}", un); /* create class groups */ aux_add2group(L, "unix{master}", "unix{any}"); aux_add2group(L, "unix{client}", "unix{any}"); @@ -98,42 +98,42 @@ int unix_open(lua_State *L) { * Just call buffered IO methods \*-------------------------------------------------------------------------*/ static int meth_send(lua_State *L) { - p_unix unix = (p_unix) aux_checkclass(L, "unix{client}", 1); - return buf_meth_send(L, &unix->buf); + p_unix un = (p_unix) aux_checkclass(L, "unix{client}", 1); + return buf_meth_send(L, &un->buf); } static int meth_receive(lua_State *L) { - p_unix unix = (p_unix) aux_checkclass(L, "unix{client}", 1); - return buf_meth_receive(L, &unix->buf); + p_unix un = (p_unix) aux_checkclass(L, "unix{client}", 1); + return buf_meth_receive(L, &un->buf); } /*-------------------------------------------------------------------------*\ * Just call option handler \*-------------------------------------------------------------------------*/ static int meth_setoption(lua_State *L) { - p_unix unix = (p_unix) aux_checkgroup(L, "unix{any}", 1); - return opt_meth_setoption(L, opt, &unix->sock); + p_unix un = (p_unix) aux_checkgroup(L, "unix{any}", 1); + return opt_meth_setoption(L, opt, &un->sock); } /*-------------------------------------------------------------------------*\ * Select support methods \*-------------------------------------------------------------------------*/ static int meth_getfd(lua_State *L) { - p_unix unix = (p_unix) aux_checkgroup(L, "unix{any}", 1); - lua_pushnumber(L, (int) unix->sock); + p_unix un = (p_unix) aux_checkgroup(L, "unix{any}", 1); + lua_pushnumber(L, (int) un->sock); return 1; } /* this is very dangerous, but can be handy for those that are brave enough */ static int meth_setfd(lua_State *L) { - p_unix unix = (p_unix) aux_checkgroup(L, "unix{any}", 1); - unix->sock = (t_sock) luaL_checknumber(L, 2); + p_unix un = (p_unix) aux_checkgroup(L, "unix{any}", 1); + un->sock = (t_sock) luaL_checknumber(L, 2); return 0; } static int meth_dirty(lua_State *L) { - p_unix unix = (p_unix) aux_checkgroup(L, "unix{any}", 1); - lua_pushboolean(L, !buf_isempty(&unix->buf)); + p_unix un = (p_unix) aux_checkgroup(L, "unix{any}", 1); + lua_pushboolean(L, !buf_isempty(&un->buf)); return 1; } @@ -145,22 +145,22 @@ static int meth_accept(lua_State *L) { p_unix server = (p_unix) aux_checkclass(L, "unix{server}", 1); p_tm tm = tm_markstart(&server->tm); t_sock sock; - const char *err = sock_accept(&server->sock, &sock, NULL, NULL, tm); + int err = sock_accept(&server->sock, &sock, NULL, NULL, tm); /* if successful, push client socket */ - if (!err) { + if (err == IO_DONE) { p_unix clnt = (p_unix) lua_newuserdata(L, sizeof(t_unix)); aux_setclass(L, "unix{client}", -1); /* initialize structure fields */ sock_setnonblocking(&sock); clnt->sock = sock; io_init(&clnt->io, (p_send)sock_send, (p_recv)sock_recv, - (p_geterr) sock_geterr, &clnt->sock); + (p_error) sock_ioerror, &clnt->sock); tm_init(&clnt->tm, -1, -1); buf_init(&clnt->buf, &clnt->io, &clnt->tm); return 1; } else { lua_pushnil(L); - lua_pushstring(L, err); + lua_pushstring(L, sock_strerror(err)); return 2; } } @@ -168,10 +168,10 @@ static int meth_accept(lua_State *L) { /*-------------------------------------------------------------------------*\ * Binds an object to an address \*-------------------------------------------------------------------------*/ -static const char *unix_trybind(p_unix unix, const char *path) { +static const char *unix_trybind(p_unix un, const char *path) { struct sockaddr_un local; size_t len = strlen(path); - const char *err; + int err; if (len >= sizeof(local.sun_path)) return "path too long"; memset(&local, 0, sizeof(local)); strcpy(local.sun_path, path); @@ -179,20 +179,20 @@ static const char *unix_trybind(p_unix unix, const char *path) { #ifdef UNIX_HAS_SUN_LEN local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len) + len + 1; - err = sock_bind(&unix->sock, (SA *) &local, local.sun_len); + err = sock_bind(&un->sock, (SA *) &local, local.sun_len); #else - err = sock_bind(&unix->sock, (SA *) &local, + err = sock_bind(&un->sock, (SA *) &local, sizeof(local.sun_family) + len); #endif - if (err) sock_destroy(&unix->sock); - return err; + if (err != IO_DONE) sock_destroy(&un->sock); + return sock_strerror(err); } static int meth_bind(lua_State *L) { - p_unix unix = (p_unix) aux_checkclass(L, "unix{master}", 1); + p_unix un = (p_unix) aux_checkclass(L, "unix{master}", 1); const char *path = luaL_checkstring(L, 2); - const char *err = unix_trybind(unix, path); + const char *err = unix_trybind(un, path); if (err) { lua_pushnil(L); lua_pushstring(L, err); @@ -205,33 +205,33 @@ static int meth_bind(lua_State *L) { /*-------------------------------------------------------------------------*\ * Turns a master unix object into a client object. \*-------------------------------------------------------------------------*/ -static const char *unix_tryconnect(p_unix unix, const char *path) +static const char *unix_tryconnect(p_unix un, const char *path) { struct sockaddr_un remote; - const char *err; + int err; size_t len = strlen(path); if (len >= sizeof(remote.sun_path)) return "path too long"; memset(&remote, 0, sizeof(remote)); strcpy(remote.sun_path, path); remote.sun_family = AF_UNIX; - tm_markstart(&unix->tm); + tm_markstart(&un->tm); #ifdef UNIX_HAS_SUN_LEN remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len) + len + 1; - err = sock_connect(&unix->sock, (SA *) &remote, remote.sun_len, &unix->tm); + err = sock_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm); #else - err = sock_connect(&unix->sock, (SA *) &remote, - sizeof(remote.sun_family) + len, &unix->tm); + err = sock_connect(&un->sock, (SA *) &remote, + sizeof(remote.sun_family) + len, &un->tm); #endif - if (err) sock_destroy(&unix->sock); - return err; + if (err != IO_DONE) sock_destroy(&un->sock); + return sock_strerror(err); } static int meth_connect(lua_State *L) { - p_unix unix = (p_unix) aux_checkclass(L, "unix{master}", 1); + p_unix un = (p_unix) aux_checkclass(L, "unix{master}", 1); const char *path = luaL_checkstring(L, 2); - const char *err = unix_tryconnect(unix, path); + const char *err = unix_tryconnect(un, path); if (err) { lua_pushnil(L); lua_pushstring(L, err); @@ -248,8 +248,8 @@ static int meth_connect(lua_State *L) \*-------------------------------------------------------------------------*/ static int meth_close(lua_State *L) { - p_unix unix = (p_unix) aux_checkgroup(L, "unix{any}", 1); - sock_destroy(&unix->sock); + p_unix un = (p_unix) aux_checkgroup(L, "unix{any}", 1); + sock_destroy(&un->sock); return 0; } @@ -258,12 +258,12 @@ static int meth_close(lua_State *L) \*-------------------------------------------------------------------------*/ static int meth_listen(lua_State *L) { - p_unix unix = (p_unix) aux_checkclass(L, "unix{master}", 1); + p_unix un = (p_unix) aux_checkclass(L, "unix{master}", 1); int backlog = (int) luaL_optnumber(L, 2, 32); - const char *err = sock_listen(&unix->sock, backlog); - if (err) { + int err = sock_listen(&un->sock, backlog); + if (err != IO_DONE) { lua_pushnil(L); - lua_pushstring(L, err); + lua_pushstring(L, sock_strerror(err)); return 2; } /* turn master object into a server object */ @@ -277,20 +277,20 @@ static int meth_listen(lua_State *L) \*-------------------------------------------------------------------------*/ static int meth_shutdown(lua_State *L) { - p_unix unix = (p_unix) aux_checkgroup(L, "unix{client}", 1); + p_unix un = (p_unix) aux_checkgroup(L, "unix{client}", 1); const char *how = luaL_optstring(L, 2, "both"); switch (how[0]) { case 'b': if (strcmp(how, "both")) goto error; - sock_shutdown(&unix->sock, 2); + sock_shutdown(&un->sock, 2); break; case 's': if (strcmp(how, "send")) goto error; - sock_shutdown(&unix->sock, 1); + sock_shutdown(&un->sock, 1); break; case 'r': if (strcmp(how, "receive")) goto error; - sock_shutdown(&unix->sock, 0); + sock_shutdown(&un->sock, 0); break; } lua_pushnumber(L, 1); @@ -304,8 +304,8 @@ error: * Just call tm methods \*-------------------------------------------------------------------------*/ static int meth_settimeout(lua_State *L) { - p_unix unix = (p_unix) aux_checkgroup(L, "unix{any}", 1); - return tm_meth_settimeout(L, &unix->tm); + p_unix un = (p_unix) aux_checkgroup(L, "unix{any}", 1); + return tm_meth_settimeout(L, &un->tm); } /*=========================================================================*\ @@ -316,24 +316,24 @@ static int meth_settimeout(lua_State *L) { \*-------------------------------------------------------------------------*/ static int global_create(lua_State *L) { t_sock sock; - const char *err = sock_create(&sock, AF_UNIX, SOCK_STREAM, 0); + int err = sock_create(&sock, AF_UNIX, SOCK_STREAM, 0); /* try to allocate a system socket */ - if (!err) { + if (err == IO_DONE) { /* allocate unix object */ - p_unix unix = (p_unix) lua_newuserdata(L, sizeof(t_unix)); + p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix)); /* set its type as master object */ aux_setclass(L, "unix{master}", -1); /* initialize remaining structure fields */ sock_setnonblocking(&sock); - unix->sock = sock; - io_init(&unix->io, (p_send) sock_send, (p_recv) sock_recv, - (p_geterr) sock_geterr, &unix->sock); - tm_init(&unix->tm, -1, -1); - buf_init(&unix->buf, &unix->io, &unix->tm); + un->sock = sock; + io_init(&un->io, (p_send) sock_send, (p_recv) sock_recv, + (p_error) sock_ioerror, &un->sock); + tm_init(&un->tm, -1, -1); + buf_init(&un->buf, &un->io, &un->tm); return 1; } else { lua_pushnil(L); - lua_pushstring(L, err); + lua_pushstring(L, sock_strerror(err)); return 2; } } diff --git a/src/usocket.c b/src/usocket.c index 0cff17b..62a2557 100644 --- a/src/usocket.c +++ b/src/usocket.c @@ -205,7 +205,7 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm) /* loop until we send something or we give up on error */ *sent = 0; for ( ;; ) { - ssize_t put = send(*ps, data, count, 0); + long put = (long) send(*ps, data, count, 0); /* if we sent anything, we are done */ if (put > 0) { *sent = put; @@ -236,7 +236,7 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, if (*ps == SOCK_INVALID) return IO_CLOSED; *sent = 0; for ( ;; ) { - ssize_t put = sendto(*ps, data, count, 0, addr, len); + long put = (long) sendto(*ps, data, count, 0, addr, len); if (put > 0) { *sent = put; return IO_DONE; @@ -257,7 +257,7 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, p_tm tm) { int err; if (*ps == SOCK_INVALID) return IO_CLOSED; for ( ;; ) { - ssize_t taken = recv(*ps, data, count, 0); + long taken = (long) recv(*ps, data, count, 0); if (taken > 0) { *got = taken; return IO_DONE; @@ -280,7 +280,7 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, int err; if (*ps == SOCK_INVALID) return IO_CLOSED; for ( ;; ) { - ssize_t taken = recvfrom(*ps, data, count, 0, addr, len); + long taken = (long) recvfrom(*ps, data, count, 0, addr, len); if (taken > 0) { *got = taken; return IO_DONE; @@ -335,7 +335,7 @@ int sock_gethostbyname(const char *addr, struct hostent **hp) { const char *sock_hoststrerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case HOST_NOT_FOUND: return "host_not_found"; + case HOST_NOT_FOUND: return "host not found"; default: return hstrerror(err); } } @@ -343,9 +343,9 @@ const char *sock_hoststrerror(int err) { const char *sock_strerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case EADDRINUSE: return "eaddrinuse"; - case EACCES: return "eaccess"; - case ECONNREFUSED: return "econnrefused"; + case EADDRINUSE: return "address already in use"; + case EACCES: return "permission denied"; + case ECONNREFUSED: return "connection refused"; case ECONNABORTED: return "closed"; case ECONNRESET: return "closed"; case ETIMEDOUT: return "timedout"; diff --git a/src/wsocket.c b/src/wsocket.c index 511dbdc..1f1e99d 100644 --- a/src/wsocket.c +++ b/src/wsocket.c @@ -309,7 +309,7 @@ int sock_gethostbyname(const char *addr, struct hostent **hp) { const char *sock_hoststrerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case WSAHOST_NOT_FOUND: return "host_not_found"; + case WSAHOST_NOT_FOUND: return "host not found"; default: return wstrerror(err); } } @@ -317,8 +317,9 @@ const char *sock_hoststrerror(int err) { const char *sock_strerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case WSAEADDRINUSE: return "eaddrinuse"; - case WSAECONNREFUSED: return "econnrefused"; + case WSAEADDRINUSE: return "address already in use"; + case WSAECONNREFUSED: return "connection refused"; + case WSAEACCES: return "permission denied"; case WSAECONNABORTED: return "closed"; case WSAECONNRESET: return "closed"; case WSAETIMEDOUT: return "timeout"; diff --git a/test/httptest.lua b/test/httptest.lua index 1f4158a..31e8212 100644 --- a/test/httptest.lua +++ b/test/httptest.lua @@ -3,8 +3,11 @@ -- needs ScriptAlias from /home/c/diego/tec/luasocket/test/cgi -- to "/luasocket-test-cgi" and "/luasocket-test-cgi/" -- needs "AllowOverride AuthConfig" on /home/c/diego/tec/luasocket/test/auth - local socket = require("socket") + +-- override protection to make sure we see all errors +-- socket.protect = function(s) return s end + local http = require("http") local mime = require("mime") local url = require("url") @@ -19,7 +22,7 @@ http.TIMEOUT = 10 local t = socket.gettime() -host = host or "diego.princeton.edu" +host = host or "diego.student.princeton.edu" proxy = proxy or "http://localhost:3128" prefix = prefix or "/luasocket-test" cgiprefix = cgiprefix or "/luasocket-test-cgi" diff --git a/test/mimetest.lua b/test/mimetest.lua index 413a83b..d549ba6 100644 --- a/test/mimetest.lua +++ b/test/mimetest.lua @@ -8,7 +8,7 @@ local qptest = "qptest.bin" local eqptest = "qptest.bin2" local dqptest = "qptest.bin3" -local b64test = "luasocket.dll" +local b64test = "luasocket.so" local eb64test = "b64test.bin" local db64test = "b64test.bin2"