]> jfr.im git - irc/quakenet/newserv.git/blame - lua/lib/socket.lua
Improve help texts for trustgroupmodify and trusthostmodify
[irc/quakenet/newserv.git] / lua / lib / socket.lua
CommitLineData
a098bb43
CP
1-- transparent non-blocking writes with buffers!
2
3local socket_write_raw = socket_write
4local socket_unix_connect_raw = socket_unix_connect
5local socket_unix_bind_raw = socket_unix_bind
6local socket_tcp_connect_raw = socket_tcp_connect
7local socket_tcp_bind_raw = socket_tcp_bind
8local socket_udp_connect_raw = socket_udp_connect
9local socket_udp_bind_raw = socket_udp_bind
10local socket_close_raw = socket_close
11
12local sockets = {}
13
41ef4405 14local function socket_handler(socket, event, tag, ...)
a098bb43
CP
15 if event == "flush" then
16 local buf = sockets[socket].writebuf
17 local ret = socket_write_raw(socket, buf)
18
19 if ret == -1 then
20 return -- close will be called
21 end
22
23 sockets[socket].writebuf = buf:sub(ret + 1)
24
25 if sockets[socket].closing and sockets[socket].writebuf == "" then
26 socket_close(socket)
27 end
28
29 -- no reason to tell the caller
30 return
31 elseif event == "accept" then
32 local newsocket = ...
33 socket_new(newsocket, sockets[socket].handler)
34 end
35
36 sockets[socket].handler(socket, event, tag, ...)
37
38 if event == "close" then
39 sockets[socket] = nil
40 end
41end
42
43function socket_new(socket, handler)
44 sockets[socket] = { writebuf = "", handler = handler }
45end
46
47function socket_unix_connect(path, handler, tag)
48 local connected, socket = socket_unix_connect_raw(path, socket_handler, tag)
49 if connected == nil then
50 return nil
51 end
52
53 socket_new(socket, handler)
54 if connected then
55 socket_handler(socket, "connect", tag)
56 end
57
58 return socket
59end
60
61function socket_unix_bind(path, handler, tag)
62 local socket = socket_unix_bind_raw(path, socket_handler, tag)
63 if not socket then
64 return nil
65 end
66
67 socket_new(socket, handler)
68 return socket
69end
70
71local function socket_ip_connect(fn, address, port, handler, tag)
41ef4405
CP
72 local connected, socket = fn(address, port, socket_handler, tag)
73
a098bb43
CP
74 if connected == nil then
75 return nil
76 end
77
78 socket_new(socket, handler)
79 if connected then
41ef4405 80 socket_handler(socket, "connect", tag)
a098bb43
CP
81 end
82
83 return socket
84end
85
86local function socket_ip_bind(fn, address, port, handler, tag)
41ef4405 87 local socket = fn(address, port, socket_handler, tag)
a098bb43
CP
88 if not socket then
89 return nil
90 end
91
92 socket_new(socket, handler)
93 return socket
94end
95
96function socket_tcp_bind(address, port, handler, tag)
97 return socket_ip_bind(socket_tcp_bind_raw, address, port, handler, tag)
98end
99
100function socket_tcp_connect(address, port, handler, tag)
101 return socket_ip_connect(socket_tcp_connect_raw, address, port, handler, tag)
102end
103
104function socket_udp_bind(address, port, handler, tag)
105 return socket_ip_bind(socket_udp_bind_raw, address, port, handler, tag)
106end
107
108function socket_udp_connect(address, port, handler, tag)
109 return socket_ip_connect(socket_udp_connect_raw, address, port, handler, tag)
110end
111
112function socket_write(socket, data)
113 if sockets[socket].writebuf == "" then
114 local ret = socket_write_raw(socket, data)
115 if ret == -1 then
116 return false -- close will be called regardless
117 end
118
119 if ret == data:len() then
120 return true
121 end
122
123 -- lua strings start at 1
124 sockets[socket].writebuf = data:sub(ret + 1)
125 else
126 sockets[socket].writebuf = sockets[socket].writebuf .. data
127 end
128
129 return true
130end
131
132function socket_close(socket, flush)
133 if whenbufferempty and sockets[socket].writebuf ~= "" then
134 sockets[socket].closing = true
135 return
136 end
137
138 return socket_close_raw(socket)
139end