diff options
| author | Diego Nehab <diego.nehab@gmail.com> | 2013-05-29 04:20:33 -0700 |
|---|---|---|
| committer | Diego Nehab <diego.nehab@gmail.com> | 2013-05-29 04:20:33 -0700 |
| commit | 5341131cd07bf4f66ce242980b5f3cfbbf45ea12 (patch) | |
| tree | 2a5db457e38cdf3de1f29df4d0217999c5cd306d | |
| parent | b84a5f3d08b1dc9d1003506bbca53e11264e8693 (diff) | |
| parent | 1de617e3550366076737e804f1e28891605db89c (diff) | |
| download | luasocket-5341131cd07bf4f66ce242980b5f3cfbbf45ea12.tar.gz luasocket-5341131cd07bf4f66ce242980b5f3cfbbf45ea12.tar.bz2 luasocket-5341131cd07bf4f66ce242980b5f3cfbbf45ea12.zip | |
Merge pull request #43 from moteus/moteus-getopt-error
Add. Allow get `error` option to socket.
| -rw-r--r-- | src/options.c | 13 | ||||
| -rw-r--r-- | src/options.h | 1 | ||||
| -rw-r--r-- | src/tcp.c | 1 | ||||
| -rw-r--r-- | src/udp.c | 1 | ||||
| -rw-r--r-- | test/test_socket_error.lua | 27 |
5 files changed, 43 insertions, 0 deletions
diff --git a/src/options.c b/src/options.c index 6cae7ee..6f36ba4 100644 --- a/src/options.c +++ b/src/options.c | |||
| @@ -254,6 +254,19 @@ static int opt_getboolean(lua_State *L, p_socket ps, int level, int name) | |||
| 254 | return 1; | 254 | return 1; |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | int opt_get_error(lua_State *L, p_socket ps) | ||
| 258 | { | ||
| 259 | int val = 0; | ||
| 260 | socklen_t len = sizeof(val); | ||
| 261 | if (getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *) &val, &len) < 0) { | ||
| 262 | lua_pushnil(L); | ||
| 263 | lua_pushstring(L, "getsockopt failed"); | ||
| 264 | return 2; | ||
| 265 | } | ||
| 266 | lua_pushstring(L, socket_strerror(val)); | ||
| 267 | return 1; | ||
| 268 | } | ||
| 269 | |||
| 257 | static int opt_setboolean(lua_State *L, p_socket ps, int level, int name) | 270 | static int opt_setboolean(lua_State *L, p_socket ps, int level, int name) |
| 258 | { | 271 | { |
| 259 | int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */ | 272 | int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */ |
diff --git a/src/options.h b/src/options.h index 55447f7..1cabd7d 100644 --- a/src/options.h +++ b/src/options.h | |||
| @@ -42,6 +42,7 @@ int opt_get_linger(lua_State *L, p_socket ps); | |||
| 42 | int opt_get_reuseaddr(lua_State *L, p_socket ps); | 42 | int opt_get_reuseaddr(lua_State *L, p_socket ps); |
| 43 | int opt_get_ip_multicast_loop(lua_State *L, p_socket ps); | 43 | int opt_get_ip_multicast_loop(lua_State *L, p_socket ps); |
| 44 | int opt_get_ip_multicast_if(lua_State *L, p_socket ps); | 44 | int opt_get_ip_multicast_if(lua_State *L, p_socket ps); |
| 45 | int opt_get_error(lua_State *L, p_socket ps); | ||
| 45 | 46 | ||
| 46 | /* invokes the appropriate option handler */ | 47 | /* invokes the appropriate option handler */ |
| 47 | int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps); | 48 | int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps); |
| @@ -73,6 +73,7 @@ static t_opt optget[] = { | |||
| 73 | {"reuseaddr", opt_get_reuseaddr}, | 73 | {"reuseaddr", opt_get_reuseaddr}, |
| 74 | {"tcp-nodelay", opt_get_tcp_nodelay}, | 74 | {"tcp-nodelay", opt_get_tcp_nodelay}, |
| 75 | {"linger", opt_get_linger}, | 75 | {"linger", opt_get_linger}, |
| 76 | {"error", opt_get_error}, | ||
| 76 | {NULL, NULL} | 77 | {NULL, NULL} |
| 77 | }; | 78 | }; |
| 78 | 79 | ||
| @@ -85,6 +85,7 @@ static t_opt optset[] = { | |||
| 85 | static t_opt optget[] = { | 85 | static t_opt optget[] = { |
| 86 | {"ip-multicast-if", opt_get_ip_multicast_if}, | 86 | {"ip-multicast-if", opt_get_ip_multicast_if}, |
| 87 | {"ip-multicast-loop", opt_get_ip_multicast_loop}, | 87 | {"ip-multicast-loop", opt_get_ip_multicast_loop}, |
| 88 | {"error", opt_get_error}, | ||
| 88 | {NULL, NULL} | 89 | {NULL, NULL} |
| 89 | }; | 90 | }; |
| 90 | 91 | ||
diff --git a/test/test_socket_error.lua b/test/test_socket_error.lua new file mode 100644 index 0000000..9bd0bc7 --- /dev/null +++ b/test/test_socket_error.lua | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | local socket = require "socket" | ||
| 2 | |||
| 3 | local host, port = "127.0.0.1", "5462" | ||
| 4 | |||
| 5 | assert(socket.bind(host, port)):close() | ||
| 6 | |||
| 7 | local sock = socket.tcp() | ||
| 8 | sock:settimeout(0) | ||
| 9 | |||
| 10 | local ok, err = sock:connect(host, port) | ||
| 11 | assert(not ok) | ||
| 12 | assert('timeout' == err) | ||
| 13 | |||
| 14 | for i = 1, 10 do | ||
| 15 | -- select pass even if socket has error | ||
| 16 | local _, rec, err = socket.select(nil, {sock}, 1) | ||
| 17 | assert('timeout' == err) | ||
| 18 | assert(not next(rec)) | ||
| 19 | err = sock:getoption("error") -- i get 'connection refused' on WinXP | ||
| 20 | if err then | ||
| 21 | print("Passed! Error is '" .. err .. "'.") | ||
| 22 | os.exit(0) | ||
| 23 | end | ||
| 24 | end | ||
| 25 | |||
| 26 | print("Fail! No error detected!") | ||
| 27 | os.exit(1) | ||
