1 -- transparent non-blocking writes with buffers!
3 local socket_write_raw = socket_write
4 local socket_unix_connect_raw = socket_unix_connect
5 local socket_unix_bind_raw = socket_unix_bind
6 local socket_tcp_connect_raw = socket_tcp_connect
7 local socket_tcp_bind_raw = socket_tcp_bind
8 local socket_udp_connect_raw = socket_udp_connect
9 local socket_udp_bind_raw = socket_udp_bind
10 local socket_close_raw = socket_close
14 local function socket_handler(socket, event, tag, ...)
15 if event == "flush" then
16 local buf = sockets[socket].writebuf
17 local ret = socket_write_raw(socket, buf)
20 return -- close will be called
23 sockets[socket].writebuf = buf:sub(ret + 1)
25 if sockets[socket].closing and sockets[socket].writebuf == "" then
29 -- no reason to tell the caller
31 elseif event == "accept" then
33 socket_new(newsocket, sockets[socket].handler)
36 sockets[socket].handler(socket, event, tag, ...)
38 if event == "close" then
43 function socket_new(socket, handler)
44 sockets[socket] = { writebuf = "", handler = handler }
47 function socket_unix_connect(path, handler, tag)
48 local connected, socket = socket_unix_connect_raw(path, socket_handler, tag)
49 if connected == nil then
53 socket_new(socket, handler)
55 socket_handler(socket, "connect", tag)
61 function socket_unix_bind(path, handler, tag)
62 local socket = socket_unix_bind_raw(path, socket_handler, tag)
67 socket_new(socket, handler)
71 local function socket_ip_connect(fn, address, port, handler, tag)
72 local connected, socket = fn(address, port, socket_handler, tag)
74 if connected == nil then
78 socket_new(socket, handler)
80 socket_handler(socket, "connect", tag)
86 local function socket_ip_bind(fn, address, port, handler, tag)
87 local socket = fn(address, port, socket_handler, tag)
92 socket_new(socket, handler)
96 function socket_tcp_bind(address, port, handler, tag)
97 return socket_ip_bind(socket_tcp_bind_raw, address, port, handler, tag)
100 function socket_tcp_connect(address, port, handler, tag)
101 return socket_ip_connect(socket_tcp_connect_raw, address, port, handler, tag)
104 function socket_udp_bind(address, port, handler, tag)
105 return socket_ip_bind(socket_udp_bind_raw, address, port, handler, tag)
108 function socket_udp_connect(address, port, handler, tag)
109 return socket_ip_connect(socket_udp_connect_raw, address, port, handler, tag)
112 function socket_write(socket, data)
113 if sockets[socket].writebuf == "" then
114 local ret = socket_write_raw(socket, data)
116 return false -- close will be called regardless
119 if ret == data:len() then
123 -- lua strings start at 1
124 sockets[socket].writebuf = data:sub(ret + 1)
126 sockets[socket].writebuf = sockets[socket].writebuf .. data
132 function socket_close(socket, flush)
133 if whenbufferempty and sockets[socket].writebuf ~= "" then
134 sockets[socket].closing = true
138 return socket_close_raw(socket)