YkLib 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +34 -0
- data/LICENSE.txt +21 -0
- data/README.md +44 -0
- data/Rakefile +6 -0
- data/YkLib.gemspec +29 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/YkLib/Yk/__advance__.rb +151 -0
- data/lib/YkLib/Yk/__defun__.rb +44 -0
- data/lib/YkLib/Yk/__hook__.rb +244 -0
- data/lib/YkLib/Yk/__minmax__.rb +123 -0
- data/lib/YkLib/Yk/__stdlog.rb +329 -0
- data/lib/YkLib/Yk/adhocLiterals/email.rb +119 -0
- data/lib/YkLib/Yk/adhocLiterals/path.rb +402 -0
- data/lib/YkLib/Yk/adhocLiterals/tag.rb +19 -0
- data/lib/YkLib/Yk/adhocLiterals/url.rb +36 -0
- data/lib/YkLib/Yk/adhocLiterals.rb +199 -0
- data/lib/YkLib/Yk/auto_escseq.rb +5 -0
- data/lib/YkLib/Yk/auto_pstore.rb +179 -0
- data/lib/YkLib/Yk/bsearch.rb +120 -0
- data/lib/YkLib/Yk/clambda.rb +309 -0
- data/lib/YkLib/Yk/confLine.rb +423 -0
- data/lib/YkLib/Yk/create_tty_width_available.rb +24 -0
- data/lib/YkLib/Yk/crypt.rb +26 -0
- data/lib/YkLib/Yk/debug2 +1 -0
- data/lib/YkLib/Yk/debug2.rb +473 -0
- data/lib/YkLib/Yk/debugout.rb +139 -0
- data/lib/YkLib/Yk/email_tz.rb +533 -0
- data/lib/YkLib/Yk/enum_expect.rb +170 -0
- data/lib/YkLib/Yk/errlog.rb +5 -0
- data/lib/YkLib/Yk/escseq.rb +59 -0
- data/lib/YkLib/Yk/eval_alt.rb +281 -0
- data/lib/YkLib/Yk/expector.rb +93 -0
- data/lib/YkLib/Yk/fetch.rb +556 -0
- data/lib/YkLib/Yk/fetch_old.rb +290 -0
- data/lib/YkLib/Yk/fib.rb +158 -0
- data/lib/YkLib/Yk/file_aux.rb +843 -0
- data/lib/YkLib/Yk/file_aux2.rb +919 -0
- data/lib/YkLib/Yk/file_aux_old.rb +160 -0
- data/lib/YkLib/Yk/filemod.rb +19 -0
- data/lib/YkLib/Yk/force_escseq.rb +3 -0
- data/lib/YkLib/Yk/generator__.rb +144 -0
- data/lib/YkLib/Yk/generator__.rb.org +139 -0
- data/lib/YkLib/Yk/indenter/argless_case.rb +46 -0
- data/lib/YkLib/Yk/indenter/each_token.rb +671 -0
- data/lib/YkLib/Yk/indenter/free_case.rb +313 -0
- data/lib/YkLib/Yk/indenter/if_less.rb +53 -0
- data/lib/YkLib/Yk/indenter/independent_ensure.rb +23 -0
- data/lib/YkLib/Yk/indenter/independent_rescue.rb +23 -0
- data/lib/YkLib/Yk/indenter/operand_circumflex.rb +0 -0
- data/lib/YkLib/Yk/indenter/operand_period.rb +16 -0
- data/lib/YkLib/Yk/indenter/parenless_and.rb +37 -0
- data/lib/YkLib/Yk/indenter/post_test.rb +48 -0
- data/lib/YkLib/Yk/indenter/token.rb +1525 -0
- data/lib/YkLib/Yk/indenter.rb +1382 -0
- data/lib/YkLib/Yk/inot.rb +265 -0
- data/lib/YkLib/Yk/intf.rb +815 -0
- data/lib/YkLib/Yk/io_aux.rb +1332 -0
- data/lib/YkLib/Yk/ioctl.rb +60 -0
- data/lib/YkLib/Yk/ipcc.rb +87 -0
- data/lib/YkLib/Yk/ipcountry.rb +207 -0
- data/lib/YkLib/Yk/ipv4adr.rb +318 -0
- data/lib/YkLib/Yk/localmail.rb +276 -0
- data/lib/YkLib/Yk/method_chain.rb +359 -0
- data/lib/YkLib/Yk/misc_tz.rb +1716 -0
- data/lib/YkLib/Yk/missing_method.rb +50 -0
- data/lib/YkLib/Yk/mojiConv.rb +257 -0
- data/lib/YkLib/Yk/nostdlog.rb +4 -0
- data/lib/YkLib/Yk/on_marshal.rb +20 -0
- data/lib/YkLib/Yk/overrider.rb +47 -0
- data/lib/YkLib/Yk/path.rb +293 -0
- data/lib/YkLib/Yk/path_aux.rb +883 -0
- data/lib/YkLib/Yk/path_aux_alt.rb +0 -0
- data/lib/YkLib/Yk/path_rep.rb +1267 -0
- data/lib/YkLib/Yk/pg_setup.rb +917 -0
- data/lib/YkLib/Yk/procinfo.rb +314 -0
- data/lib/YkLib/Yk/proclist.rb +492 -0
- data/lib/YkLib/Yk/property.rb +863 -0
- data/lib/YkLib/Yk/ranger.rb +606 -0
- data/lib/YkLib/Yk/resolv_tz.rb +88 -0
- data/lib/YkLib/Yk/rlprompt.rb +73 -0
- data/lib/YkLib/Yk/rootexec.rb +48 -0
- data/lib/YkLib/Yk/rpm-packageproxy.rb +784 -0
- data/lib/YkLib/Yk/rpm-packageproxy2.rb +1430 -0
- data/lib/YkLib/Yk/rwhen.rb +21 -0
- data/lib/YkLib/Yk/selector.rb +124 -0
- data/lib/YkLib/Yk/set.rb +170 -0
- data/lib/YkLib/Yk/shellquote.rb +300 -0
- data/lib/YkLib/Yk/sio.rb +1001 -0
- data/lib/YkLib/Yk/sio0.rb +835 -0
- data/lib/YkLib/Yk/sio_aux.rb +1524 -0
- data/lib/YkLib/Yk/sio_inot.rb +86 -0
- data/lib/YkLib/Yk/sock_aux.rb +42 -0
- data/lib/YkLib/Yk/spipe.rb +843 -0
- data/lib/YkLib/Yk/sql_table.rb +565 -0
- data/lib/YkLib/Yk/stdlog.rb +4 -0
- data/lib/YkLib/Yk/syscommand.rb +173 -0
- data/lib/YkLib/Yk/sysinit.rb +75 -0
- data/lib/YkLib/Yk/ttyFontWidth.rb +46113 -0
- data/lib/YkLib/Yk/tty_char.dump +0 -0
- data/lib/YkLib/Yk/tty_char.rb +47 -0
- data/lib/YkLib/Yk/tty_char_create.rb +437031 -0
- data/lib/YkLib/Yk/tty_char_static.rb +437016 -0
- data/lib/YkLib/Yk/tty_rewrite.rb +142 -0
- data/lib/YkLib/Yk/tty_str.rb +461 -0
- data/lib/YkLib/Yk/tty_width.dat.rb +114 -0
- data/lib/YkLib/Yk/tty_width.rb +180 -0
- data/lib/YkLib/Yk/tty_width_available +569 -0
- data/lib/YkLib/Yk/tty_width_list +0 -0
- data/lib/YkLib/Yk/tty_width_list.linux +280 -0
- data/lib/YkLib/Yk/tty_width_list.windows +324 -0
- data/lib/YkLib/Yk/tz_tty +0 -0
- data/lib/YkLib/Yk/tz_tty.rb +0 -0
- data/lib/YkLib/Yk/uprepos.rb +94 -0
- data/lib/YkLib/Yk/userinfo.rb +91 -0
- data/lib/YkLib/Yk/with.rb +109 -0
- data/lib/YkLib/version.rb +3 -0
- data/lib/YkLib.rb +6 -0
- metadata +170 -0
|
@@ -0,0 +1,835 @@
|
|
|
1
|
+
require 'Yk/path_aux'
|
|
2
|
+
require 'net/smtp'
|
|
3
|
+
require 'base64'
|
|
4
|
+
require 'uri'
|
|
5
|
+
require 'net/dns'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
IPv4Regexp = /^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class IO
|
|
12
|
+
def set_sio mode = nil
|
|
13
|
+
@sio = SIO.new self, mode
|
|
14
|
+
end
|
|
15
|
+
def sio
|
|
16
|
+
@sio
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class String
|
|
22
|
+
SIOServers = Hash.new
|
|
23
|
+
def to_ip
|
|
24
|
+
SIOResolver.resolv self
|
|
25
|
+
end
|
|
26
|
+
def __open tmode, &prc
|
|
27
|
+
self =~ /:/
|
|
28
|
+
adr, port = $`, $'
|
|
29
|
+
if adr !~ /^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/
|
|
30
|
+
p
|
|
31
|
+
adr = adr.to_ip
|
|
32
|
+
p
|
|
33
|
+
end
|
|
34
|
+
s = TCPSocket.new(adr, port.to_i)
|
|
35
|
+
s.set_sio tmode
|
|
36
|
+
if prc
|
|
37
|
+
begin
|
|
38
|
+
prc.call s.sio
|
|
39
|
+
ensure
|
|
40
|
+
s.sio.close
|
|
41
|
+
end
|
|
42
|
+
else
|
|
43
|
+
s.sio
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
def open_T &prc
|
|
47
|
+
__open :text, &prc
|
|
48
|
+
end
|
|
49
|
+
def open &prc
|
|
50
|
+
__open :binary, &prc
|
|
51
|
+
end
|
|
52
|
+
def __listen tmode
|
|
53
|
+
self =~ /:/
|
|
54
|
+
adr, port = $`, $'
|
|
55
|
+
if adr !~ /^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/
|
|
56
|
+
adr = adr.to_ip
|
|
57
|
+
end
|
|
58
|
+
sio = nil
|
|
59
|
+
begin
|
|
60
|
+
sio = (SIOServers[self] ||= SIO.new(TCPServer.new(adr, port.to_i)))
|
|
61
|
+
loop do
|
|
62
|
+
SIO.select sio, :read
|
|
63
|
+
sio.io.accept do |s|
|
|
64
|
+
s.set_sio tmode
|
|
65
|
+
SIO.fork do
|
|
66
|
+
yield s.sio
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
ensure
|
|
71
|
+
sio.close
|
|
72
|
+
SIOServers.delete self
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
def listen
|
|
76
|
+
__listen :binary
|
|
77
|
+
end
|
|
78
|
+
def listen_T
|
|
79
|
+
__listen :text
|
|
80
|
+
end
|
|
81
|
+
def url_encode
|
|
82
|
+
URI.url_escape self
|
|
83
|
+
end
|
|
84
|
+
def url_decode
|
|
85
|
+
URI.url_unescape self
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class Integer
|
|
91
|
+
def listen &prc
|
|
92
|
+
"0.0.0.0:#{self}".listen &prc
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def local *args
|
|
98
|
+
yield *args
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class SIO
|
|
103
|
+
class ExpectException < Exception
|
|
104
|
+
end
|
|
105
|
+
attr :io
|
|
106
|
+
def initialize io, m
|
|
107
|
+
@io = io
|
|
108
|
+
@mode = m
|
|
109
|
+
@readBuff = ""
|
|
110
|
+
@residue = ""
|
|
111
|
+
end
|
|
112
|
+
def expect arg
|
|
113
|
+
loop do
|
|
114
|
+
@readBuff.lstrip!
|
|
115
|
+
break if @readBuff.size > 0
|
|
116
|
+
pre_read
|
|
117
|
+
end
|
|
118
|
+
p @readBuff
|
|
119
|
+
while @readBuff.size < arg.size && @readBuff == arg[0...@readBuff.size] && !@eof
|
|
120
|
+
pre_read
|
|
121
|
+
end
|
|
122
|
+
if @readBuff.size < arg.size
|
|
123
|
+
raise ExceptException.new "expected '#{arg}', but '#{@readBuff}' returned\n"
|
|
124
|
+
else
|
|
125
|
+
p @readBuff
|
|
126
|
+
@readBuff = @readBuff[arg.size ... @readBuff.size]
|
|
127
|
+
p @readBuff
|
|
128
|
+
return arg
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
def expectln arg = nil
|
|
132
|
+
if arg
|
|
133
|
+
expect arg + "\n"
|
|
134
|
+
else
|
|
135
|
+
loop do
|
|
136
|
+
if @readBuff.size == 0
|
|
137
|
+
if !@eof
|
|
138
|
+
pre_read
|
|
139
|
+
else
|
|
140
|
+
raise ExceptException.new "expected empty new line but reached eof\n"
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
if @eof
|
|
144
|
+
if @readBuff !~ /^[\t\f\r ]*\n/
|
|
145
|
+
if @readBuff.size == 0
|
|
146
|
+
raise ExceptException.new "expected empty new line but reached eof\n"
|
|
147
|
+
else
|
|
148
|
+
raise ExceptException.new "expected empty new line but read '#{@readBuff}'\n"
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
@readBuff = $'
|
|
152
|
+
while @readBuff =~ /^[\t\f\r ]*\n/
|
|
153
|
+
@readBuff = $'
|
|
154
|
+
end
|
|
155
|
+
return
|
|
156
|
+
else
|
|
157
|
+
while @readBuff =~ /^[\t\f\r ]+/
|
|
158
|
+
@readBuff = $'
|
|
159
|
+
if @readBuff.size == 0
|
|
160
|
+
pre_read
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
if @eof && @readBuff == ""
|
|
164
|
+
raise ExceptException.new "expected empty new line but reached eof\n"
|
|
165
|
+
end
|
|
166
|
+
if @readBuff[0] != "\n"
|
|
167
|
+
raise ExceptException.new "expected empty new line but read '#{@readBuff}'\n"
|
|
168
|
+
end
|
|
169
|
+
@readBuff = @readBuff[1...@readBuff.size]
|
|
170
|
+
loop do
|
|
171
|
+
while @readBuff =~ /^[\t\f\r ]+/
|
|
172
|
+
if $'.size > 0
|
|
173
|
+
break
|
|
174
|
+
elsif @eof # $'.size == 0
|
|
175
|
+
return
|
|
176
|
+
end
|
|
177
|
+
pre_read
|
|
178
|
+
end
|
|
179
|
+
if @readBuff[0] == "\n"
|
|
180
|
+
@readBuff = @readBuff[1...@readBuff.size]
|
|
181
|
+
next
|
|
182
|
+
end
|
|
183
|
+
return
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
def readline
|
|
190
|
+
idx = nil
|
|
191
|
+
res = @readBuff
|
|
192
|
+
@readBuff = ""
|
|
193
|
+
while !(idx = res.index "\n") && !@eof
|
|
194
|
+
pre_read
|
|
195
|
+
res += @readBuff
|
|
196
|
+
@readBuff = ""
|
|
197
|
+
end
|
|
198
|
+
p idx
|
|
199
|
+
if idx
|
|
200
|
+
ret = res[0..idx]
|
|
201
|
+
@readBuff = res[idx + 1 ... res.size]
|
|
202
|
+
else
|
|
203
|
+
ret = res
|
|
204
|
+
end
|
|
205
|
+
ret
|
|
206
|
+
end
|
|
207
|
+
def read_each_line
|
|
208
|
+
p
|
|
209
|
+
loop do
|
|
210
|
+
p
|
|
211
|
+
ret = readline
|
|
212
|
+
if ret != ""
|
|
213
|
+
yield ret
|
|
214
|
+
end
|
|
215
|
+
if @eof && (!@readBuff || @readBuff == "")
|
|
216
|
+
return
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
def read
|
|
221
|
+
ret = ""
|
|
222
|
+
while !@eof
|
|
223
|
+
pre_read
|
|
224
|
+
ret += @readBuff
|
|
225
|
+
@readBuff = ""
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
def unwind s
|
|
229
|
+
@readBuff = s + @readBuff
|
|
230
|
+
end
|
|
231
|
+
def select_write
|
|
232
|
+
self.class.select self, :write
|
|
233
|
+
end
|
|
234
|
+
def select_read
|
|
235
|
+
return if @eof
|
|
236
|
+
p
|
|
237
|
+
self.class.select self, :read
|
|
238
|
+
p
|
|
239
|
+
begin
|
|
240
|
+
@readBuff += @io.readpartial 0x3fffffff
|
|
241
|
+
p @readBuff
|
|
242
|
+
rescue EOFError
|
|
243
|
+
p
|
|
244
|
+
@eof = true
|
|
245
|
+
end
|
|
246
|
+
p
|
|
247
|
+
end
|
|
248
|
+
def write arg
|
|
249
|
+
if @mode == :text
|
|
250
|
+
arg = arg.gsub "\n", "\r\n"
|
|
251
|
+
end
|
|
252
|
+
select_write
|
|
253
|
+
p arg
|
|
254
|
+
return @io.write arg
|
|
255
|
+
end
|
|
256
|
+
def writeln arg
|
|
257
|
+
write arg + "\n"
|
|
258
|
+
end
|
|
259
|
+
def pre_read
|
|
260
|
+
loop do
|
|
261
|
+
if @readBuff.size > 0
|
|
262
|
+
break
|
|
263
|
+
end
|
|
264
|
+
@readBuff += @residue
|
|
265
|
+
p
|
|
266
|
+
select_read
|
|
267
|
+
p @readBuff
|
|
268
|
+
if @mode == :text
|
|
269
|
+
@readBuff.gsub! "\r\n", "\n"
|
|
270
|
+
if @mode == :text && @readBuff[-1] == "\r"
|
|
271
|
+
@readBuff.chop!
|
|
272
|
+
@residue = "\r"
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
if @readBuff != "" || @eof
|
|
276
|
+
break
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
def close
|
|
281
|
+
@io.close
|
|
282
|
+
end
|
|
283
|
+
def self.continue_procs
|
|
284
|
+
@main_cont.call
|
|
285
|
+
end
|
|
286
|
+
def self.exit
|
|
287
|
+
if @proc_to_select.size > 0
|
|
288
|
+
@select_one.call
|
|
289
|
+
else
|
|
290
|
+
Kernel.exit status
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
class OrderedQueue < Array
|
|
296
|
+
def initialize &prc
|
|
297
|
+
@ev = prc
|
|
298
|
+
end
|
|
299
|
+
alias :_insert_at :insert
|
|
300
|
+
def _insert item, bg = 0, ed = size
|
|
301
|
+
if @ev.call(bg) == @ev.call(ed - 1)
|
|
302
|
+
_insert ed - 1, item
|
|
303
|
+
else
|
|
304
|
+
if ed - bg == 1
|
|
305
|
+
_insert_at ed, item
|
|
306
|
+
elsif ed - bg == 2
|
|
307
|
+
_insert_at ed - 1, item
|
|
308
|
+
else
|
|
309
|
+
m = (bg + ed).div 2
|
|
310
|
+
if @ev.call(item) < @ev.call(self[m])
|
|
311
|
+
_insert item, bg, m + 1
|
|
312
|
+
elsif @ev.call(self[m + 1]) <= @ev.call(item)
|
|
313
|
+
_insert item, m + 1, ed
|
|
314
|
+
else
|
|
315
|
+
_insert_at m + 1, item
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
def insert item
|
|
321
|
+
if size == 0
|
|
322
|
+
push item
|
|
323
|
+
else
|
|
324
|
+
if @ev.call(self[0]) > @ev.call(item)
|
|
325
|
+
unshift item
|
|
326
|
+
elsif @ev.call(self[-1]) <= @ev.call(item)
|
|
327
|
+
push item
|
|
328
|
+
else
|
|
329
|
+
_insert item
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
class ForkObj
|
|
337
|
+
def awake_at t
|
|
338
|
+
SIO.proc_to_select.each do |prc|
|
|
339
|
+
if prc.forkObj == self && prc.sio._?.is_a?(Time).__it > t
|
|
340
|
+
prc.set_sio t
|
|
341
|
+
break
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
def exit
|
|
346
|
+
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
def self.forkObj
|
|
350
|
+
@forkObj ||= ForkObj.new
|
|
351
|
+
end
|
|
352
|
+
def self.fork mode = false, &prc # mode : true, execute block firstly
|
|
353
|
+
cc = callcc do |cont|
|
|
354
|
+
cont
|
|
355
|
+
end
|
|
356
|
+
p cc
|
|
357
|
+
if cc.is_a? Continuation
|
|
358
|
+
cc_frk = callcc do |cont|
|
|
359
|
+
cont
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
p cc, cc_frk
|
|
363
|
+
case [cc.is_a?(Continuation), cc_frk.is_a?(Continuation)]
|
|
364
|
+
when [true, true]
|
|
365
|
+
cc, cc_frk = cc_frk, cc if mode
|
|
366
|
+
(@proc_to_select ||= []).push SIOProc.new(cc, :pass)
|
|
367
|
+
@proc_to_select.push SIOProc.new(cc_frk, :fork)
|
|
368
|
+
@select_one.call
|
|
369
|
+
when [false, true]
|
|
370
|
+
cc = cc_frk
|
|
371
|
+
begin
|
|
372
|
+
prc.call
|
|
373
|
+
rescue Exception => ex
|
|
374
|
+
ex.instance_eval {
|
|
375
|
+
STDERR.write "#{backtrace[0]}:#{ex} (#{self.class})".ln
|
|
376
|
+
backtrace[1..-1].each do |e|
|
|
377
|
+
STDERR.write " " + e.ln
|
|
378
|
+
end
|
|
379
|
+
}
|
|
380
|
+
@aborted = true
|
|
381
|
+
abort
|
|
382
|
+
end
|
|
383
|
+
if @proc_to_select.size > 0
|
|
384
|
+
@select_one.call
|
|
385
|
+
else
|
|
386
|
+
raise Exception.new "unknown fork finalization error\n"
|
|
387
|
+
end
|
|
388
|
+
when [true, false]
|
|
389
|
+
cc_frk = cc
|
|
390
|
+
return forkObj
|
|
391
|
+
else
|
|
392
|
+
raise Exception.new "unknown fork finalization error\n"
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
def self.pass
|
|
396
|
+
cc = callcc do |cont|
|
|
397
|
+
cont
|
|
398
|
+
end
|
|
399
|
+
if cc.is_a? Continuation
|
|
400
|
+
(@proc_to_select ||= []).push SIOProc.new(cc, :pass)
|
|
401
|
+
@select_one.call
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
def self.sleep t = :stop
|
|
405
|
+
cc = callcc do |cont|
|
|
406
|
+
cont
|
|
407
|
+
end
|
|
408
|
+
if cc.is_a? Continuation
|
|
409
|
+
t != :stop and t += Time.now
|
|
410
|
+
(@proc_to_select ||= []).push SIOProc.new(cc, t)
|
|
411
|
+
@select_one.call
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
def self.stopBy token, timeout = :stop
|
|
415
|
+
cc = callcc do |cont|
|
|
416
|
+
cont
|
|
417
|
+
end
|
|
418
|
+
if cc.is_a? Continuation
|
|
419
|
+
(@proc_to_select ||= []).push SIOProc.new(cc, timeout, token)
|
|
420
|
+
@select_one.call
|
|
421
|
+
else
|
|
422
|
+
if cc == :start
|
|
423
|
+
:timeout
|
|
424
|
+
else
|
|
425
|
+
token
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
def self.awakeBy token
|
|
430
|
+
cc = callcc do |cont|
|
|
431
|
+
cont
|
|
432
|
+
end
|
|
433
|
+
if cc.is_a? Continuation
|
|
434
|
+
(@proc_to_select ||= []).each do |prc|
|
|
435
|
+
if prc.token == token
|
|
436
|
+
prc.set_sio :start
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
(@proc_to_select ||= []).push SIOProc.new(cc, :start)
|
|
440
|
+
@select_one.call
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
def self.timer t
|
|
444
|
+
loop do
|
|
445
|
+
yield
|
|
446
|
+
sleep t
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
def self.select_one
|
|
450
|
+
p5
|
|
451
|
+
cc = callcc do |cont|
|
|
452
|
+
cont
|
|
453
|
+
end
|
|
454
|
+
if cc.is_a? Continuation
|
|
455
|
+
@select_one = cc
|
|
456
|
+
else
|
|
457
|
+
wios = []
|
|
458
|
+
rios = []
|
|
459
|
+
active_procs = []
|
|
460
|
+
hasTimer = false
|
|
461
|
+
@proc_to_select.each do |prc|
|
|
462
|
+
if prc.timeout
|
|
463
|
+
hasTimer = true
|
|
464
|
+
break
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
now = Time.now if hasTimer
|
|
468
|
+
tmout = nil
|
|
469
|
+
tmoutList = []
|
|
470
|
+
wio2SIOPrc = Hash.new{|h, k| h[k] = []}
|
|
471
|
+
rio2SIOPrc = Hash.new{|h, k| h[k] = []}
|
|
472
|
+
p
|
|
473
|
+
@proc_to_select.each do |prc|
|
|
474
|
+
p prc.selected?, prc.mode
|
|
475
|
+
case prc.selected? || prc.mode
|
|
476
|
+
when :read, :write
|
|
477
|
+
if prc.mode == :read
|
|
478
|
+
rio2SIOPrc[prc.io].push prc
|
|
479
|
+
rios.push prc.io
|
|
480
|
+
else # :write
|
|
481
|
+
wio2SIOPrc[prc.io].push prc
|
|
482
|
+
wios.push prc.io
|
|
483
|
+
end
|
|
484
|
+
if prc.timeout
|
|
485
|
+
if !tmout || (tmout != 0 and tmout > prc.timeout - now and tmoutList.clear)
|
|
486
|
+
tmout = prc.timeout - now
|
|
487
|
+
tmout = 0 if tmout < 0
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
when :timer
|
|
491
|
+
if !tmout
|
|
492
|
+
tmout = prc.timeout - now
|
|
493
|
+
tmout = 0 if tmout < 0
|
|
494
|
+
tmoutList.push prc
|
|
495
|
+
elsif tmout == 0 && prc.timeout - now <= 0
|
|
496
|
+
tmoutList.push prc
|
|
497
|
+
elsif tmout == prc.timeout - now
|
|
498
|
+
tmoutList.push prc
|
|
499
|
+
elsif tmout > prc.timeout - now
|
|
500
|
+
tmout = prc.timeout - now
|
|
501
|
+
tmout = 0 if tmout < 0
|
|
502
|
+
tmoutList.clear
|
|
503
|
+
tmoutList.push prc
|
|
504
|
+
end
|
|
505
|
+
when :stop
|
|
506
|
+
# do nothing
|
|
507
|
+
when :start, true
|
|
508
|
+
if !tmout
|
|
509
|
+
tmout = 0
|
|
510
|
+
tmoutList.push prc
|
|
511
|
+
elsif tmout == 0
|
|
512
|
+
tmoutList.push prc
|
|
513
|
+
else
|
|
514
|
+
tmout = 0
|
|
515
|
+
tmoutList.clear
|
|
516
|
+
tmoutList.push prc
|
|
517
|
+
end
|
|
518
|
+
when :pass
|
|
519
|
+
prc.set_sio :start
|
|
520
|
+
else # token
|
|
521
|
+
# do nothing
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
# p @proc_to_select
|
|
525
|
+
p tmout
|
|
526
|
+
p [rios, wios, tmoutList]
|
|
527
|
+
selectedList, srios, swios = nil
|
|
528
|
+
if !tmout || tmout != 0
|
|
529
|
+
begin
|
|
530
|
+
srios, swios, = IO.select rios, wios, [], tmout
|
|
531
|
+
rescue Errno::EINTR
|
|
532
|
+
retry
|
|
533
|
+
end
|
|
534
|
+
now = nil
|
|
535
|
+
timeouted = (!srios || srios.size == 0) && (!swios || swios.size == 0)
|
|
536
|
+
[[rios, srios, rio2SIOPrc], [wios, swios, wio2SIOPrc]].each do |ios, sios, io2SIOPrc|
|
|
537
|
+
ios.each do |io|
|
|
538
|
+
io2SIOPrc[io].each do |e|
|
|
539
|
+
if (sios && sios.include?(io)) || (e.timeout && e.timeout < (now ||= Time.now))
|
|
540
|
+
e.set_selected
|
|
541
|
+
(selectedList ||= []).push e
|
|
542
|
+
end
|
|
543
|
+
end
|
|
544
|
+
end
|
|
545
|
+
end
|
|
546
|
+
else #tmout = 0
|
|
547
|
+
timeouted = true
|
|
548
|
+
end
|
|
549
|
+
p rios
|
|
550
|
+
p wios
|
|
551
|
+
p selectedList
|
|
552
|
+
p tmoutList
|
|
553
|
+
if timeouted
|
|
554
|
+
(selectedList ||= []).push *tmoutList
|
|
555
|
+
end
|
|
556
|
+
current_proc = selectedList.shuffle[0]
|
|
557
|
+
current_proc.reset_selected if current_proc.selected?
|
|
558
|
+
@proc_to_select.delete current_proc
|
|
559
|
+
@forkObj = current_proc.forkObj
|
|
560
|
+
p current_proc
|
|
561
|
+
current_proc.continue
|
|
562
|
+
end
|
|
563
|
+
end
|
|
564
|
+
def self.select sio, mode, timeout = nil
|
|
565
|
+
prc = SIOProc.new
|
|
566
|
+
if prc.set_cont sio, mode, timeout
|
|
567
|
+
(@proc_to_select ||= []).push prc
|
|
568
|
+
@select_one.call
|
|
569
|
+
end
|
|
570
|
+
end
|
|
571
|
+
class SIOProc
|
|
572
|
+
attr_reader :mode, :sio, :forkObj, :timeout, :token
|
|
573
|
+
def io
|
|
574
|
+
if sio.is_a? SIO
|
|
575
|
+
sio.io
|
|
576
|
+
else
|
|
577
|
+
sio
|
|
578
|
+
end
|
|
579
|
+
end
|
|
580
|
+
def initialize *args
|
|
581
|
+
args.each do |e|
|
|
582
|
+
case e
|
|
583
|
+
when Continuation
|
|
584
|
+
@cont = e
|
|
585
|
+
when :fork
|
|
586
|
+
@mode = :start
|
|
587
|
+
@forkObj = ForkObj.new
|
|
588
|
+
when Symbol
|
|
589
|
+
@mode = e
|
|
590
|
+
when Time
|
|
591
|
+
@timeout = e
|
|
592
|
+
when Numeric
|
|
593
|
+
@timeout = Time.now + e
|
|
594
|
+
else
|
|
595
|
+
@token = e
|
|
596
|
+
end
|
|
597
|
+
end
|
|
598
|
+
@timeout and @mode ||= :timer
|
|
599
|
+
@forkObj ||= SIO.forkObj
|
|
600
|
+
end
|
|
601
|
+
def set_sio t
|
|
602
|
+
if t.is_a? Time
|
|
603
|
+
@mode = :timer
|
|
604
|
+
@timeout = t
|
|
605
|
+
elsif t == :pass
|
|
606
|
+
@mode = :pass
|
|
607
|
+
@sio = nil
|
|
608
|
+
elsif t == :start
|
|
609
|
+
@mode = :start
|
|
610
|
+
@sio = nil
|
|
611
|
+
end
|
|
612
|
+
end
|
|
613
|
+
def set_cont sio, mode, timeout
|
|
614
|
+
@sio = sio
|
|
615
|
+
@mode = mode
|
|
616
|
+
if timeout
|
|
617
|
+
@timeout = timeout.is_a?(Numeric) ? timeout + Time.now : timeout
|
|
618
|
+
end
|
|
619
|
+
cc = callcc do |cont|
|
|
620
|
+
cont
|
|
621
|
+
end
|
|
622
|
+
if cc.is_a? Continuation
|
|
623
|
+
@cont = cc
|
|
624
|
+
true
|
|
625
|
+
else
|
|
626
|
+
false
|
|
627
|
+
end
|
|
628
|
+
end
|
|
629
|
+
def set_selected
|
|
630
|
+
@selected = true
|
|
631
|
+
end
|
|
632
|
+
def reset_selected
|
|
633
|
+
@selected = false
|
|
634
|
+
end
|
|
635
|
+
def selected?
|
|
636
|
+
return @selected
|
|
637
|
+
end
|
|
638
|
+
def continue
|
|
639
|
+
@sio = nil
|
|
640
|
+
mode = @mode
|
|
641
|
+
@mode = nil
|
|
642
|
+
@cont.call mode
|
|
643
|
+
end
|
|
644
|
+
end
|
|
645
|
+
def self.proc_to_select
|
|
646
|
+
@proc_to_select ||= []
|
|
647
|
+
end
|
|
648
|
+
def self._exit
|
|
649
|
+
if @proc_to_select.size > 0
|
|
650
|
+
@select_one.call
|
|
651
|
+
end
|
|
652
|
+
end
|
|
653
|
+
STDIN = ::STDIN.set_sio
|
|
654
|
+
STDOUT = ::STDOUT.set_sio
|
|
655
|
+
STDERR = ::STDOUT.set_sio
|
|
656
|
+
def tmode= m
|
|
657
|
+
@mode = m
|
|
658
|
+
end
|
|
659
|
+
def tmode
|
|
660
|
+
@mode
|
|
661
|
+
end
|
|
662
|
+
self.select_one
|
|
663
|
+
at_exit do
|
|
664
|
+
if $!
|
|
665
|
+
$!.instance_eval {
|
|
666
|
+
STDERR.write "#{backtrace[0]}:#{$!} (#{self.class})".ln
|
|
667
|
+
backtrace[1..-1].each do |e|
|
|
668
|
+
STDERR.write " " + e.ln
|
|
669
|
+
end
|
|
670
|
+
}
|
|
671
|
+
@aborted = true
|
|
672
|
+
abort
|
|
673
|
+
end
|
|
674
|
+
if !@aborted && proc_to_select.size > 0
|
|
675
|
+
p
|
|
676
|
+
pass
|
|
677
|
+
end
|
|
678
|
+
end
|
|
679
|
+
end
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
class String
|
|
683
|
+
def strip_indent
|
|
684
|
+
mn = 1000000
|
|
685
|
+
last = nil
|
|
686
|
+
each_line do |ln|
|
|
687
|
+
break if (last = ln)[-1] != "\n"
|
|
688
|
+
ln.chomp =~ /^\s*/
|
|
689
|
+
next if $'.size == 0
|
|
690
|
+
if $&.size < mn
|
|
691
|
+
mn = $&.size
|
|
692
|
+
end
|
|
693
|
+
end
|
|
694
|
+
res = ""
|
|
695
|
+
each_line do |ln|
|
|
696
|
+
break if ln[-1] != "\n"
|
|
697
|
+
res += ln[mn..-1] if ln[mn..-1]
|
|
698
|
+
end
|
|
699
|
+
if last && last.size <= mn
|
|
700
|
+
res += last.lstrip
|
|
701
|
+
else
|
|
702
|
+
res += last[mn..-1]
|
|
703
|
+
end
|
|
704
|
+
replace(res)
|
|
705
|
+
self
|
|
706
|
+
end
|
|
707
|
+
end
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
class SIOResolver
|
|
711
|
+
Sock = SIO.new UDPSocket.open, :read
|
|
712
|
+
begin
|
|
713
|
+
Sock.io.bind("0.0.0.0", rand(1024..65535))
|
|
714
|
+
rescue => Errno::EADDRINUSE
|
|
715
|
+
retry
|
|
716
|
+
end
|
|
717
|
+
resolvers = []
|
|
718
|
+
"/etc/resolv.conf".read_each_line do |ln|
|
|
719
|
+
if ln.strip =~ /nameserver\s*/ && $' =~ IPv4Regexp
|
|
720
|
+
resolvers.push $&
|
|
721
|
+
end
|
|
722
|
+
end
|
|
723
|
+
Resolvers = resolvers
|
|
724
|
+
MaxRetrial = 5
|
|
725
|
+
EachResolvTimeout = 0.2
|
|
726
|
+
ResolvTimeout = 1.01
|
|
727
|
+
|
|
728
|
+
p
|
|
729
|
+
SIO.fork true do
|
|
730
|
+
p
|
|
731
|
+
loop do
|
|
732
|
+
p
|
|
733
|
+
SIO.select Sock, :read
|
|
734
|
+
p
|
|
735
|
+
pkt = Sock.io.recvfrom(1024)
|
|
736
|
+
parsed = Net::DNS::Packet::parse(pkt)
|
|
737
|
+
name, ip, ttl = nil
|
|
738
|
+
parsed.question.each do |rr|
|
|
739
|
+
p rr.qType.to_s
|
|
740
|
+
p rr.qType.to_s.class
|
|
741
|
+
if rr.qType.to_s == "A"
|
|
742
|
+
name = rr.qName
|
|
743
|
+
if name[-1..-1] == "."
|
|
744
|
+
name.chop!
|
|
745
|
+
end
|
|
746
|
+
break
|
|
747
|
+
end
|
|
748
|
+
end
|
|
749
|
+
parsed.answer.each do |rr|
|
|
750
|
+
if rr.type == "A"
|
|
751
|
+
ip, ttl = rr.address.to_s, rr.ttl
|
|
752
|
+
break
|
|
753
|
+
end
|
|
754
|
+
end
|
|
755
|
+
if ip and name
|
|
756
|
+
p [name, ip, ttl]
|
|
757
|
+
Status[name].setResult ip, ttl
|
|
758
|
+
p
|
|
759
|
+
SIO.awakeBy [self, name]
|
|
760
|
+
p
|
|
761
|
+
end
|
|
762
|
+
end
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
p
|
|
766
|
+
class Status
|
|
767
|
+
attr_reader :expiry, :ip
|
|
768
|
+
def self.[] name
|
|
769
|
+
@list ||= Hash.new{|h, k| h[k] = Status.new(k)}
|
|
770
|
+
@list[name]
|
|
771
|
+
end
|
|
772
|
+
def initialize name
|
|
773
|
+
@name = name
|
|
774
|
+
@expiry = Time.at(0)
|
|
775
|
+
end
|
|
776
|
+
def resolve
|
|
777
|
+
p
|
|
778
|
+
if @resolving
|
|
779
|
+
p
|
|
780
|
+
@retrialLeft = MaxRetrial
|
|
781
|
+
return
|
|
782
|
+
end
|
|
783
|
+
p
|
|
784
|
+
@resolving = true
|
|
785
|
+
p
|
|
786
|
+
@retrialLeft = MaxRetrial
|
|
787
|
+
p
|
|
788
|
+
SIO.fork do
|
|
789
|
+
p
|
|
790
|
+
begin
|
|
791
|
+
p
|
|
792
|
+
pkt = Net::DNS::Packet.new @name
|
|
793
|
+
p
|
|
794
|
+
begin
|
|
795
|
+
p
|
|
796
|
+
@retrialLeft -= 1
|
|
797
|
+
p
|
|
798
|
+
Sock.io.send(pkt.data, 0, Resolvers[rand(0...Resolvers.size)], 53)
|
|
799
|
+
p
|
|
800
|
+
if !SIO.stopBy [self, @name], EachResolvTimeout
|
|
801
|
+
p
|
|
802
|
+
redo if @retrialLeft > 0
|
|
803
|
+
end
|
|
804
|
+
p
|
|
805
|
+
end
|
|
806
|
+
ensure
|
|
807
|
+
@resolving = false
|
|
808
|
+
end
|
|
809
|
+
end
|
|
810
|
+
p
|
|
811
|
+
end
|
|
812
|
+
def setResult ip, ttl
|
|
813
|
+
@ip = ip
|
|
814
|
+
@expiry = Time.now + ttl
|
|
815
|
+
end
|
|
816
|
+
end
|
|
817
|
+
|
|
818
|
+
def self.resolv name
|
|
819
|
+
stat = Status[name]
|
|
820
|
+
if stat.expiry > Time.now
|
|
821
|
+
return stat.ip
|
|
822
|
+
end
|
|
823
|
+
p
|
|
824
|
+
stat.resolve
|
|
825
|
+
p
|
|
826
|
+
SIO.stopBy [self, name], ResolvTimeout
|
|
827
|
+
p stat.ip
|
|
828
|
+
return stat.ip
|
|
829
|
+
end
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
end
|
|
833
|
+
|
|
834
|
+
p
|
|
835
|
+
|