aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/options.c13
-rw-r--r--src/options.h1
-rw-r--r--src/tcp.c1
-rw-r--r--src/udp.c1
-rw-r--r--test/test_socket_error.lua27
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
257int 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
257static int opt_setboolean(lua_State *L, p_socket ps, int level, int name) 270static 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);
42int opt_get_reuseaddr(lua_State *L, p_socket ps); 42int opt_get_reuseaddr(lua_State *L, p_socket ps);
43int opt_get_ip_multicast_loop(lua_State *L, p_socket ps); 43int opt_get_ip_multicast_loop(lua_State *L, p_socket ps);
44int opt_get_ip_multicast_if(lua_State *L, p_socket ps); 44int opt_get_ip_multicast_if(lua_State *L, p_socket ps);
45int opt_get_error(lua_State *L, p_socket ps);
45 46
46/* invokes the appropriate option handler */ 47/* invokes the appropriate option handler */
47int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps); 48int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps);
diff --git a/src/tcp.c b/src/tcp.c
index efb92c9..6594bda 100644
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -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
diff --git a/src/udp.c b/src/udp.c
index ec805b6..5945dca 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -85,6 +85,7 @@ static t_opt optset[] = {
85static t_opt optget[] = { 85static 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 @@
1local socket = require "socket"
2
3local host, port = "127.0.0.1", "5462"
4
5assert(socket.bind(host, port)):close()
6
7local sock = socket.tcp()
8sock:settimeout(0)
9
10local ok, err = sock:connect(host, port)
11assert(not ok)
12assert('timeout' == err)
13
14for 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
24end
25
26print("Fail! No error detected!")
27os.exit(1)